这已经是我发送过关于这个子喷气机的几篇帖子了,如果这困扰你们中的一些人,我会道歉。在玩了几天并尝试不同的替代方案(模式)之后,我得出了以下结论,这使我能够更好地阐述我的问题。
我有一个Base *
的向量,并且有从Base派生的各种Derived<T>
类。不同的类参数T在开头用前向声明声明。我需要的是从这个vector<Base *>
中取出一对对象并使用模板应用function(Derived<T1> obj1, Derived<T2> obj2)
以进行某种双重调度。但是,当我从向量中获取一个元素时,我无法将指向Base的指针转换为指向Derived的指针。因此,我无法使用function(Derived<T1> obj1, Derived<T2> obj2)
。
当然,这可以使用dynamic_cast<Derived<T> *>(base_ptr)
简单地实现。然而,这不是我想要的,因为要做到这一点,必须事先知道T,这不是这里的情况。我必须能够从矢量中选择任何元素,而不知道他们的Derived<T>
类型。
因此,我尝试了多态克隆。虽然它使用了协变返回类型,但不幸的是,它没有用。正如不同人在SO中所解释的那样,并且根据C ++标准,原因是在编译时,编译器仍然不知道对象的完整类型。因此,虽然我们希望clone()返回Derived<T> *
,但它会返回Base *
。
接下来的几行代码表达了我的意思。 通常,多态克隆用于以下情况:
Base *b1 = new Derived;
Base *b2;
b2 = b1->clone();
这不是我想要的。我需要的是一个指向派生的指针:
Base *b1 = new Derived;
Derived *d1;
d1 = b1->clone(); // This is what I want, but it fails.
这里,编译器抱怨说类型Base *
的对象不能分配给Derived *
类型的对象。因此,我无法在*d1
中使用function(,)
。
我也尝试过非虚拟接口(NVI)方法,但它没有用。
有没有人知道如何解决上面的简单代码,特别是最后一行?非常感谢提前。
答案 0 :(得分:3)
您想要的是不可能的,因为无法保证Base *
指向的对象实际上是Derived
的实例。
您可以做的最多是为clone()
函数使用协变返回类型。
class Base
{
public:
virtual Base* clone() const
{
return new Base(*this);
};
virtual ~Base() {};
};
class Derived : public Base
{
public:
virtual Derived* clone() const // note different return type
// this does override the inherited version
{
return new Derived(*this);
}
};
int main()
{
Base *b = new Derived;
Derived *d1 = b->clone(); // this does not work
Derived *o = new Derived;
Derived *d = o->clone(); // this works
}
如果要从Base *
克隆到Derived *
,则需要进行运行时检查并强制进行类型转换。
Base *b = new Derived;
Base *temp = b->clone();
Derived *d = dynamic_cast<Derived *>(temp);
if (d)
{
// d is actually an instance of Derived so can be used as such
}
else
{
// The cloning did not produce a Derived. Cope with it
}
delete temp; // this will delete the object pointed to by d, since it is the same object
然而,一般而言,您所要求的是有缺陷设计的积极指标。一般而言(假设您需要具有多态基础的类层次结构),您需要设计Base
,因此其接口(特别是虚拟函数集,可能由派生类专门化)足以满足所有用户的需要。上课做他们需要的。 Base
所需的所有用户都需要指向Base
的指针或引用(即Base &
或Base *
),并且不需要他们从Base
投射{1}}到Derived
。查看“利斯科夫替代原则”以获取更多信息。
答案 1 :(得分:0)
我认为在这种情况下你应该进行施法。你可以谷歌更多关于static_Cast和reinterpret_cast。以下是一些参考文献:How to force implicit conversion in polymorphism,Proper way of casting pointer types