该应用程序定义了 3 个要在插件中实现的接口。Widget
永远是基础。
// Application code...
class Widget {
virtual void animate() = 0;
};
class BigWidget : public Widget {
};
class SmallWidget : public Widget {
};
每个接口实现都派生自NiceWidget
其中,提供了一些插件内部的公共信息。
// Plug-in code...
class NiceWidget {
// nice::Thing is only known in plug-in code.
nice::Thing thing();
};
class NiceBigWidget : public NiceWidget, public BigWidget {
void animate() override;
};
class NiceSmallWidget : public NiceWidget, public SmallWidget {
void animate() override;
};
func
从应用程序代码中调用。wid
已知由该插件实现。因此 wid 也是一个NiceWidget
. 的目标func
是调用thing
它的方法。
// Plugin-in code...
void func(Widget* wid) {
// wid is either NiceBigWidget or NiceSmallWidget.
auto castedBig = dynamic_cast<NiceBigWidget*>(wid);
if (castedBig) {
castedBig->thing().foo();
return;
}
auto castedSmall = dynamic_cast<NiceSmallWidget*>(wid);
if (castedSmall) {
castedSmall->thing().foo();
return;
}
assert(false);
}
但是随着层次结构大小的增加,尝试对wid
每个人都进行强制转换会变得非常糟糕。Nice*
有更好的解决方案吗?