And*_*ida 22 c++ polymorphism pointers
#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;
}
Run Code Online (Sandbox Code Playgroud)
我现在有一些多态性问题,上面的代码总结了一切.我创建了一个Base类指针,并在其中放置了一个新的派生模板类的指针.然后我为派生模板类创建了一个新指针,我希望它具有基类指针指向的引用.即使Base指针(b)指向Derived,也不能将引用传递给Derived类指针(d),因为there's no known conversion from Base * to Derived<int> *(正如编译器所说).
那么有没有一种技巧或另一种方法可以做到这一点?提前致谢.
Abr*_*as2 42
您必须将基本类型更改为多态:
class Base {
public:
Base() {};
virtual ~Base(){};
};
Run Code Online (Sandbox Code Playgroud)
要从某些超类型转换为某种派生类型,您应该使用dynamic_cast:
Base *b = new Derived<int>(1);
Derived<int> *d = dynamic_cast<Derived<int> *>(b);
Run Code Online (Sandbox Code Playgroud)
dynamic_cast在这里使用检查可以进行类型转换.如果没有必要进行检查(因为演员表不能失败),你也可以使用static_cast:
Base *b = new Derived<int>(1);
Derived<int> *d = static_cast<Derived<int> *>(b);
Run Code Online (Sandbox Code Playgroud)
您可以使用dynamic_cast
Derived<int> * d = dynamic_cast<Derived<int> *>(b);
Run Code Online (Sandbox Code Playgroud)
如果转换失败(基指针未指向请求的派生类型),则返回 null。
然而,要使dynamic_cast发挥作用,你的基类必须至少有一个虚函数。我建议您将析构函数设为虚拟(这也可以防止删除对象时出现其他潜在问题)。
使用dynamic_cast可能表明代码中的设计不好。
请注意,如果您 100% 确定基指针指向您的派生类型,那么您可以将其替换为 static_cast,这会稍微快一些。就我个人而言,我更喜欢一般的额外安全检查。
尝试这个:
Derived<int> * d = static_cast<Derived<int>* >(b);
Run Code Online (Sandbox Code Playgroud)
缺点是,您可以转换 Base() 实例的类,然后 d->raw() 将是未定义的(类似分段错误)。如果是这种情况,请使用dynamic_cast并至少有一个基于virtual的函数(在使用多态性时,具有virtual析构函数是必不可少的)。
虚拟函数是在底层使用虚拟表上的指针实现的。该指针还可用于识别类的真实类型。Dynamic_cast 使用它来检查此转换是否可以完成,并在转换时带来少量额外开销。