我有一个如下所示的结构:
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,用于代码的其他部分。鉴于此,是否有一种常见的模式来解决侧面-下转换问题,而不使用
dynamic_cast
和RTTI的需要,假设我已经知道一个MyType
类继承自特定的trait
?我正在尝试找到一个聪明的解决方案,因为它是代码的重要瓶颈。
virtual Foo* AsFoo() { return nullptr; }
,然后在Foo中放入Foo* AsFoo() override { return this; }
。 - Eljaydynamic_cast
的情况下对其进行分析,因为我没有解决方案,但是我已经对dynamic_cast
所花费的时间进行了分析,所以我已经确定它是一个相当大的瓶颈。 - Jackstd::unique_ptr
替换wrapper
?这意味着你可以在那些(理想情况下很少的)需要确切派生类型的地方使用std::unique_ptr<MyType1>
或std::unique_ptr<MyType2>
,并且可以始终将其转换为std::unique_ptr<managed_object>
以供通用代码使用,从而实现完全的类型安全。 - alter_igel