c ++ - 将基类指针转换为派生类指针

时间:2013-09-18 13:42:01

标签: c++ pointers polymorphism

#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> *(正如编译器所说)。

有没有一种技巧或另一种方法可以做到这一点?提前谢谢。

3 个答案:

答案 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使用它来检查是否可以完成此转换,并在转换时带来额外的小额开销。