#include <iostream>
using namespace std;
class Base {
public:
Base() {};
~Base() {};
};
template<class T>
class Derived: public Base {
T _val;
public:
Derived() {}
Derived(T val): _val(val) {}
T raw() {return _val;}
};
int main()
{
Base * b = new Derived<int>(1);
Derived<int> * d = b;
cout << d->raw() << endl;
return 0;
}
我现在有一些多态性问题,上面的代码总结了一切。我创建了一个Base类指针,并在其中放置了一个新的派生模板类的指针。然后我为派生模板类创建了一个新指针,我希望它具有基类指针指向的引用。即使Base指针(b)指向Derived,也不能将引用传递给Derived类指针(d),因为there's no known conversion from Base * to Derived<int> *
(正如编译器所说)。
有没有一种技巧或另一种方法可以做到这一点?提前谢谢。
答案 0 :(得分:38)
您必须将基本类型更改为多态:
class Base {
public:
Base() {};
virtual ~Base(){};
};
要从某些超类型转换为某种派生类型,您应该使用dynamic_cast
:
Base *b = new Derived<int>(1);
Derived<int> *d = dynamic_cast<Derived<int> *>(b);
在此处使用dynamic_cast
检查是否可以进行类型转换。如果不需要执行该检查(因为强制转换不能失败),您也可以使用static_cast
:
Base *b = new Derived<int>(1);
Derived<int> *d = static_cast<Derived<int> *>(b);
答案 1 :(得分:2)
您可以使用dynamic_cast
Derived<int> * d = dynamic_cast<Derived<int> *>(b);
如果强制转换失败(基指针未指向请求的派生类型),则返回null。
但是,要使dynamic_cast正常工作,您的基类必须至少具有一个虚函数。我建议你将析构函数设为虚拟(这也可以防止删除对象的其他潜在问题)。
使用dynamic_cast可能表示代码设计错误。
请注意,如果您100%确定基指针指向派生类型,那么您可以将其替换为static_cast,这稍微快一点。我个人更喜欢额外的安全检查。
答案 2 :(得分:2)
试试这个:
Derived<int> * d = static_cast<Derived<int>* >(b);
缺点是,你可以转换为Base()实例的类,然后d-&gt; raw()将是未定义的(分段错误)。如果可能是这种情况,请使用dynamic_cast并且至少有一个函数ob base virtual(在使用polmorphism时,析构函数是必不可少的)。
使用虚拟表上的指针实现虚拟功能。此指针还可用于标识真正的类类型。 dynamic_cast使用它来检查是否可以完成此转换,并在转换时带来额外的小额开销。