我有一个设计问题,我不确定如何以最佳方式处理。我希望我的代码能够经得起 future 考验,并且仍然不会变得困惑和复杂(极客的困境)。
目前我的设计有以下设置
derived class D derived class E
^ ^
| |
derived abstract class B -> derived class C
^ ^
| |
Abstract Base class A
类 B
不同于类 A
,类 D
和类 E
不同于类 B
和 C
不同于类 A
。
由于这些类不同,我需要使用 dynamic_cast
运算符。
A* a1 = new class C;
C* c1 = dynamics_cast<C*>(a1);
if(c1){ //Success!!!}
...
如您所见,我会经常使用 dynamic_cast
!我需要尝试找到一种很好的方法来执行此操作,它不包含额外的 if()
语句。
有没有一种巧妙的方法来做到这一点?我似乎记得在 Scott Meyers 的书中看到过一些东西,但我不在家,一两周内无法访问它。
任何引用/示例将不胜感激。
此外,如果需要,我可以将类 B
变成一个接口(interface),这将是一种解决方案
B* d1 = new D;
B* e1 = new E;
但并不理想。
注意:我添加了这个例子来展示我当前的设计失败
class A {...};
class B: public A {
public:
virtual std::vector<objectType1*>& getObjectType1();
};
class C: public B {
private:
void newFunction();
};
A* c1 = new C();
std::vector<objectType1*> example = c1->getObjectType1(); // Wrong; need dyanmic_cast :-(
在没有dynamic_cast
的情况下无法访问getObjectType1()
,因为静态类型A 不知道此函数。我需要重新考虑我的设计。有什么想法吗?
最佳答案
在设计得当的对象层次结构中,dynamic_cast
的使用很少见。当然,它的存在是为了向上和向下转换多态树,但这并不意味着您必须使用它。
想想这个。一般来说,为什么需要使用 dynamic_cast
?因为您拥有的基指针没有提供您需要的设施,对吗?多态性的意义何在?为类似的操作提供不同的行为,在运行时选择行为,对吗?
这两个说法是不是有些矛盾?如果您的对象接口(interface)设计正确,那么当您调用 ->Foo()
时,您并不真正关心将采用哪种行为——您只想调用 ->Foo()
。
如果您需要经常使用dynamic_cast
,它是一种代码味道,告诉您您的接口(interface)有问题。也许您正试图将太多东西塞进一个界面?
关于c++ - dynamic_cast 和多态性的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10549284/