C++ 如何避免C++;特定类方法的强制转换?设计模式?
假设我有这样的东西:C++ 如何避免C++;特定类方法的强制转换?设计模式?,c++,inheritance,casting,design-patterns,C++,Inheritance,Casting,Design Patterns,假设我有这样的东西: class Father { public: virtual int genericMethod (void) =0; }; class Son1: public Father { public: int genericMethod () { } }; class Son2: public Father { public: int genericMethod () { } int spe
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!
Father * test = new Son1();
SpecificInterface * specificAPI = test->getSpecificInterface();
if( specificAPI )
specificAPI->specifClassCmethod();
这里的主要问题是了解通过父接口访问Son2特定方法的更好方法。我想知道是否有一种设计模式可以解决这个问题或其他问题。我不想做演员,也不想在我的代码中加入很多“如果”
问候,
Eduardo否。要调用仅存在于子类中的方法,必须强制转换到child类
虽然您可以创建一个映射,将函数名映射到函数,但可以从子类的构造函数中将函数添加到映射中,然后使用类似于
test->callMethod(“name”)代码>您必须使所有这些方法具有相同的签名,或者使用varargs来传递参数,这不是很好。否。要调用仅存在于子类中的方法,您必须强制转换到child类
虽然您可以创建一个映射,将函数名映射到函数,但可以从子类的构造函数中将函数添加到映射中,然后使用类似于test->callMethod(“name”)
您必须使所有这些方法具有相同的签名,或者使用varargs来传递参数,这不是很好。您可以static_cast(test)->specifyClassCmethod()代码>但只有当父*测试=新Son2()时,这才有效代码>您可以静态转换(测试)->指定ClassCmethod()代码>但只有当父*测试=新Son2()时,这才有效
如果您确实有一些特定于Son2
的内容,那么您应该使用动态播放。如果可以使用默认的空行为将其作为虚拟函数添加到基类中,那么您可以不用强制转换来解决问题(但这并不是您在问题中所说的那样)
解决问题的一种设计模式是使用。该对象将具有所有易于调用的方法,并将它们委托给真实对象或不委托给真实对象
代理模式的优点:
- 您可以集中将后面的对象区分到一个位置所需的逻辑
- 您可以轻松添加一些日志记录
- 客户端代码保持简单,
Son
类清除了多余的内容
如果您确实有特定于Son2
的内容,那么您应该使用dynamic\u cast
。如果可以使用默认的空行为将其作为虚拟函数添加到基类中,那么您可以不用强制转换来解决问题(但这并不是您在问题中所说的那样)
解决问题的一种设计模式是使用。该对象将具有所有易于调用的方法,并将它们委托给真实对象或不委托给真实对象
代理模式的优点:
- 您可以集中将后面的对象区分到一个位置所需的逻辑
- 您可以轻松添加一些日志记录
- 客户端代码保持简单,
Son
类清除了多余的内容
您也不能通过强制转换合法地解决这个问题,因为“test”指向的是父对象,而不是Son2对象。强制转换对象类型意味着“相信我,编译器,这个变量实际上包含X”。它不会以某种方式神奇地将基础对象转换为派生对象;它只会告诉编译器一些你已经知道它不知道的东西
如果您希望行为因派生类而异,则将该行为移动到虚拟方法中——即,希望调用specificCLassMethod()的代码属于父类的虚拟方法。您也无法通过强制转换合法解决此问题,因为“test”指向的是父对象,而不是Son2对象。强制转换对象类型意味着“相信我,编译器,这个变量实际上包含X”。它不会以某种方式神奇地将基础对象转换为派生对象;它只会告诉编译器一些你已经知道它不知道的东西
如果希望行为因派生类而异,则将该行为移动到虚拟方法中——即,希望调用specificCLassMethod()的代码属于父类的虚拟方法。可能访问者模式就是您要寻找的模式
也许访问者模式就是您要寻找的模式
首先,您不能为类“父”创建实例,因为它是一个抽象类(具有虚int-genericMethod(void)=0;-纯虚函数)。相反,可以为它分配一个实例
像
首先,您不能为类“父”创建实例,因为它是一个抽象类(具有虚拟int-genericMethod(void)=0;-纯虚拟函数)。相反,可以为其分配一个实例
像
可能的方法是使用带有可选方法的特定接口,以及在基类(可能返回零)中获取此接口的虚拟方法:
用途如下:
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!
Father * test = new Son1();
SpecificInterface * specificAPI = test->getSpecificInterface();
if( specificAPI )
specificAPI->specifClassCmethod();
可能的方法是使用带有可选方法的特定接口,以及在基类(可能返回零)中获取此接口的虚拟方法:
用途如下:
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!
Father * test = new Son1();
SpecificInterface * specificAPI = test->getSpecificInterface();
if( specificAPI )
specificAPI->specifClassCmethod();
你的例子有点做作,有可能让它更具体吗?为了比@Coda更明确,你正在使用的实际设计是什么,这样我们可以指出其中的缺陷?如果你的设计还可以,那么dynamic\u cast
就是你的朋友。通常,使用dynamic\u cast
是嗅到代码的标志。不要忘记向基类添加虚拟析构函数。否则删除“父*test=…;删除test;”将不会调用正确的析构函数。您的示例有点做作,是否有可能使其更具体?为了比@Coda更明确,您使用的实际设计是什么,以便我们指出其中的缺陷?如果你的设计还可以,那么dynamic\u cast
就是你的朋友。通常,usi