我正在尝试重构一些代码,同时保留现有功能。我无法将指向对象的指针转换为基接口,然后在以后获取派生类。在某些情况下,程序使用工厂对象来创建这些对象的实例。
以下是我正在使用的课程的一些示例。
// This is the one I'm working with now that is causing all the trouble.
// Some, but not all methods in NewAbstract and OldAbstract overlap, so I
// used virtual inheritance.
class MyObject : virtual public NewAbstract, virtual public OldAbstract { ... }
// This is what it looked like before
class MyObject : public OldAbstract { ... }
// This is an example of most other classes that use the base interface
class NormalObject : public ISerializable
// The two abstract classes. They inherit from the same object.
class NewAbstract : public ISerializable { ... }
class OldAbstract : public ISerializable { ... }
// A factory object used to create instances of ISerializable objects.
template<class T> class Factory
{
public:
...
virtual ISerializable* createObject() const
{
return static_cast<ISerializable*>(new T()); // current factory code
}
...
}
This question可以很好地了解不同类型的铸件的作用,但它并没有帮助我弄清楚这种情况。使用static_cast和常规转换会给我error C2594: 'static_cast': ambiguous conversions from 'MyObject *' to 'ISerializable *'
。使用dynamic_cast会导致createObject()返回NULL。 NormalObject样式类和旧版MyObject与工厂中现有的static_cast一起使用。
有没有办法让这个演员工作?看起来应该是可能的。
答案 0 :(得分:10)
你必须虚拟继承ISerializable(我刚用VS2010测试过)。这是一个称为 Diamond问题的常见问题,编译器不知道要采用的层次结构路径。
编辑:
这应该这样做:
class NewAbstract : public virtual ISerializable { ... }
class OldAbstract : public virtual ISerializable { ... }
答案 1 :(得分:1)
你可以先把它转移到你的一个直接基地,例如。
virtual ISerializable* createObject() const
{
NewAbstract*const na = dynamic_cast< NewAbstract* >( new T() );
return dynamic_cast< ISerializable* >( na );
}
答案 2 :(得分:0)
不要从NewAbstract和OldAbstract中虚拟继承。选择一个从虚拟继承。我认为可以照顾它。
答案 3 :(得分:-2)
查找“可怕的钻石”和虚拟继承。他们可能会帮助你。