假设我有这样的事情:
class Father {
public:
virtual int genericMethod (void) =0;
};
class Son1: public Father {
public:
int genericMethod ()
{ }
};
class Son2: public Father {
public:
int genericMethod ()
{ }
int specifClassMethod()
{ }
};
在主要内容中,我执行以下操作:
Father * test = new Son2();
test->specifClassMethod(); //Can't do this! It is specific of Class Son2 and is not a virtual method in class Father!
这里的主要问题是了解通过父接口访问Son2特定方法的更好方法。我想知道是否有设计模式来解决这个问题或其他方式。我不想做演员表,我也不想在我的代码中加入很多'if'。
此致
爱德华
答案 0 :(得分:2)
也许访客模式是您正在寻找的模式。
答案 1 :(得分:2)
可能的方法是使用可选方法的特定接口,以及在基类中获取此接口的虚拟方法(可能返回零):
class SpecificInterface {
public:
virtual ~SpecificInterface()
{ }
virtual int specifClassCmethod() = 0;
{ }
};
class Father {
public:
virtual int genericMethod (void) = 0;
virtual SpecificInterface* getSpecificInterface (void) =0;
};
class Son1: public Father {
public:
int genericMethod ()
{ }
SpecificInterface* getSpecificInterface (void)
{ return 0; }
};
class Son2: public Father, public SpecificInterface {
public:
int genericMethod ()
{ }
int specifClassCmethod()
{ }
SpecificInterface* getSpecificInterface (void)
{ return this; }
};
用法如下:
Father * test = new Son1();
SpecificInterface * specificAPI = test->getSpecificInterface();
if( specificAPI )
specificAPI->specifClassCmethod();
答案 2 :(得分:1)
你也无法通过演员合法解决这个问题,因为“test”指的是一个Father对象,而不是一个Son2对象。转换对象类型意味着“相信我,编译器,这个变量实际上包含X”。它不会以某种方式神奇地将基础对象转换为派生对象;它只告诉编译器你已经知道它没有的东西。
如果您希望行为与派生类不同,则将行为移动到虚拟方法中 - 即,想要调用specificCLassMethod()的代码属于父虚拟方法。
答案 3 :(得分:0)
没有。要调用仅存在于子类中的方法,您必须转换为ch ild类。
虽然您可以创建一个将函数名称映射到函数的映射,但是可以从子类的构造函数向它添加函数,然后使用test->callMethod("name");
之类的函数来使所有这些函数具有相同的签名或使用varargs传递不太好的参数。
答案 4 :(得分:0)
您可以static_cast<Son2*>(test)->specifClassCmethod();
,但仅在Father * test = new Son2();
答案 5 :(得分:0)
如果您确实拥有Son2
特有的内容,那么dynamic_cast<>
就是您应该使用的内容。如果它可以作为虚函数添加到具有默认空行为的基类,那么您可以在没有强制转换的情况下解决您的问题(但这不是您在问题中所述的那样做)
解决您问题的一种设计模式是使用proxy object。该对象可以调用所有方法,并将它们委托给真实对象。
代理模式的优点:
Son
类可以从额外的东西中清除答案 6 :(得分:0)
首先,你不能为“父”类创建一个实例,因为它是一个抽象类(它有一个虚拟的int genericMethod(void)= 0; -pure虚函数)。而不是一个实例可以分配给它....
像
Son1* obj_son = new Son1();
Father* obj = obj_son;
//now if you call generic method - son1 method will be called(Father method is over ridden)
obj->genericMethod();
//similarly for son2 class
Son2* obj_son2 = new Son2();
Father* obj2 = obj_son2;
obj2->genericMethod();
obj2->specifClassCmethod();