【发布时间】:2018-10-26 18:10:06
【问题描述】:
我的结构如下:
struct managed_object {
virtual ~managed_object() { }
};
class trait1 {
public:
virtual void myMethod() const = 0;
};
class trait2 {
public:
virtual void myOtherMethod(int x) const = 0;
};
class MyType final : public managed_object, public trait1 {
...
};
class MyType2 final : public managed_object, public trait1, public trait2 {
...
};
class wrapper {
private:
managed_object* ptr;
public:
template<typename T> T* object() const {
return dynamic_cast<T*>(data.ptr);
}
};
所以基本上我有一个managed_object 基类,多个类型从该基类继承。这些子类型中的每一个都可以从任何特征组合继承,它们是final,所以我确信它们不会有更深层次的继承。
代码的工作要归功于 RTTI,它承担了将所有东西粘合在一起的负担,但要付出代价,否则
wrapper w = ...
trait* asTrait1 = w.object<trait1>;
不起作用,因为 managed_object 和 trait1 类型之间没有直接关系。
在我的完整代码中,我已经确定所有 dynamic_cast 都不会失败,因为我有额外的数据(示例中未显示),它为我提供了代码其他部分所需的一种 RTTI。
鉴于此,假设我已经知道 MyType 类继承自一个特定的trait?我正在尝试找到一个聪明的解决方案,因为它是代码的严重瓶颈。
【问题讨论】:
-
在基类中,您可以添加数十个(数百个?)像
virtual Foo* AsFoo() { return nullptr; }这样的getter-casters,然后在Foo 中放入Foo* AsFoo() override { return this; }。 -
你怎么知道它是代码的严重瓶颈?您是否在没有 RTTI 的情况下进行了分析来验证它?
-
@marcinj:没有
dynamic_cast,我无法分析它,因为我没有解决方案,但是是的,我分析了在dynamic_cast-ing 中花费了多少时间,所以我已经确定它是相当的瓶颈 -
您是否考虑将
wrapper替换为std::unique_ptr?这意味着您可以在精确派生类型很重要的那些(理想情况下为少数)地方使用具有完全类型安全性的std::unique_ptr<MyType1>或std::unique_ptr<MyType2>,然后您始终可以将其转换为std::unique_ptr<managed_object>用于泛型代码。跨度> -
似乎奇怪的重复模板模式(CRTP)是要走的路。
标签: c++ c++14 multiple-inheritance rtti dynamic-cast