假设我想避免
dynamic_cast
在以下代码中:
struct Base { ... stuff ... };
struct HasColor {
virtual Color getColor() const = 0;
virtual void setColor(Color) = 0;
};
struct Foo : public Base, public HasColor {
... implements HasColor methods
};
...
vector<Base*> collection;
...
for(auto element : collection) {
if(auto hasColor = dynamic_cast<HasColor*>(element)) {
hasColor->SetColor(myColor);
}
}
一种解决方案是向downcast添加一个方法:
struct Base {
HasColor* toHasColor() { return nullptr; }
};
struct Foo : public Base, public HasColor {
...
HasColor* toHasColor() { return this; }
};
但这意味着
Base
需要了解
Has
接口,增加耦合。
让我们试试访客模式:
struct BaseVisitor {
void visitHasColor(HasColor& hasColor) = 0
};
struct Base {
virtual void visit(BaseVisitor& visitor) = 0;
};
但我们只剩下一个问题:每个问题
有
类需要添加到
BaseVisitor
导致更多的耦合和更多的重新编译(这是C++,每个修改到
底座
意思是等几分钟)。
如果我想支持插件,情况会更糟。插件无法修改
底座
或
基本访问者
,因此插件无法添加其他
有
课程。(我意识到典型的C++ RTTI在库之间可能不太好,但是我已经看到了一个定制RTTI系统,显然是QT中的一个。
我能避开RTTI吗/
动态铸造
同时保持代码的可扩展性?
This question
看起来很相似。在我的例子中,我首先愿意使用其他方法来表示我的数据。
(建议避免
动态铸造
在C++样式指南中,如
this one
(第页)