Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为每个实例重新定义方法_C++_Oop - Fatal编程技术网

C++ 为每个实例重新定义方法

C++ 为每个实例重新定义方法,c++,oop,C++,Oop,只有一个独特的人叫做乔。与Peter和Steve相同。他们所做的事情有一些独特之处。我可能会产生数百个man实例,我需要为每个实例重新定义do\u something()函数 我不喜欢两次尝试: 1) Joe作为一个从人类继承而来的单身阶级。 2) 将函数指针传递给do\u something() 我想为man的每个实例重新定义do\u something()函数。可能吗?是的。看看战略设计模式: #包括 #包括 #包括 班主任{ 公众: man(std::string const&name)

只有一个独特的
叫做
。与
Peter
Steve
相同。他们所做的事情有一些独特之处。我可能会产生数百个
man
实例,我需要为每个实例重新定义
do\u something()
函数

我不喜欢两次尝试: 1)
Joe
作为一个从人类继承而来的单身阶级。 2) 将函数指针传递给
do\u something()


我想为
man
的每个实例重新定义
do\u something()
函数。可能吗?

是的。看看战略设计模式:

#包括
#包括
#包括
班主任{
公众:
man(std::string const&name):name(u(name){}
虚拟空间做某事{

std::cout最简单的方法是将操作作为参数传递给构造函数

您可以使用
std::function
或lambda。 或者创建另一个“action”类


如果您从中继承了所需的具体内容,那么每个
人都可以使用
do\u something
方法中的操作。

一个简单的方法是使用
std::function
自定义行为:

class Action
{
public:
    virtual ~Action();
    virtual void something() = 0;
};
#包括
#包括
班主任{
公众:
std::函数某物;
void do_something(){something();}
}
int main(){
乔、彼得、史蒂夫;

Joe.something=[](){std::cout解决方案1:标记分派

您只需添加一个类型并编写行为

#include <iostream>
#include <functional>

class man {
  public:
    std::function<void()> something;
    void do_something() { something(); }
}

int main(){
  man Joe, Peter, Steve;
  Joe.something = [] () { std::cout << "Joe something."; };
  Joe.do_something();
  Peter.something = [] () { std::cout << "Peter something."; };
  Peter.do_something();
  Steve.something = [] () { std::cout << "Steve something."; };
  Steve.do_something();

  return 0;
}

struct Joe{void do(){std::cout为每个人的“角色”创建一个子类Man,并初始化实例,该实例有自己的实现来覆盖do_something?是的,使
void do_something
成为成员变量,如
void(do_something*)(void)
并为每个实例分配一个唯一的函数,即
man-Joe;Joe.do_something=[](){/*函数体*/};
(您也可以将函数传递给
man
s c'tor)我没有投反对票。这是一个明显的OO模式,值得一提——但可能把细节放在答案中,而不仅仅是一个链接?可能投反对票是因为原始指针std::string没有名为equals(Java?)的成员IMO不相信直接传递字符串而不是乔实例是更好的,并且没有一个链接的解释。给我一秒钟,我仍然写的不是太过java的ISH而不是C++吗?为什么动态分配和样板字符串解析?我真的喜欢策略模式的灵活性。唯一的地方不同的人Woul。d已知将在具体的类实现中,而不是在标题中。因此,只有cpp文件才会有所有的
#include
条目。这确实是我能想到的最明智的模式之一。除了Factory/Prototype,它很接近,但更多的是一种结构模式,而不是一种行为模式。但是,你会被否决:(将它们分成不同的类型似乎有点低效,最终你会错过迭代它们和类似编译器之类的东西(或者至少是单一的)赋值定义。@It's Minghome提供一个抽象类AbsMan并遍历它就足够了基本上
Joe
是它自己的类型。我宁愿从man继承并使其成为一个单例类(我对单例类过敏)@Moia是的,但是您会有开销,并且无法在运行时生成新类型。@user3600124您必须以某种方式定义
Joe
不是
Peter
。标记分派和模板方法模式可以委托实现。这是一种“组合重于继承”方法。继承和单例也可以做到这一点,但我并不建议这样做。
class Action
{
public:
    virtual ~Action();
    virtual void something() = 0;
};
#include <iostream>
#include <functional>

class man {
  public:
    std::function<void()> something;
    void do_something() { something(); }
}

int main(){
  man Joe, Peter, Steve;
  Joe.something = [] () { std::cout << "Joe something."; };
  Joe.do_something();
  Peter.something = [] () { std::cout << "Peter something."; };
  Peter.do_something();
  Steve.something = [] () { std::cout << "Steve something."; };
  Steve.do_something();

  return 0;
}
struct Joe{ void do(){std::cout << "drink";} };
struct Peter{ void do(){std::cout << "smoke";} };
struct Steve{ void do(){std::cout << "sleep";} };

class man {
  public:
   template<typename T>
   void do_something(){ T.do();}
}
struct man_detail{}
struct Joe : public man_detail{ void do(){std::cout << "drink";} };
struct Peter : public man_detail{ void do(){std::cout << "smoke";} };
struct Steve : public man_detail{ void do(){std::cout << "sleep";} };

class man{
public:
   man(man_detail md) : maninfo(md){}

   void do_something() { maninfo.do(); }

private:
   man_detail maninfo;
};
struct Joe{};
struct Peter{};
struct Steve{};

template <typename T>
class man
{
   void do_something() {}
}

template <Joe> void man::do_something(){std::cout << "drink";}
template <Peter> void man::do_something(){std::cout << "smoke";}
template <> void man::do_something(){std::cout << "sleep";}