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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18873871/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 22:16:41  来源:igfitidea点击:

c++ - converting a base class pointer to a derived class pointer

c++pointerspolymorphism

提问by Andy Autida

#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;
}

I have some polymorphism problem right now and the code above summarizes everything. I created a Base class pointer and I put the pointer of a new derived template class in it. Then I created a new pointer for the derived template class and I want it to have the reference the base class pointer points to. Even though Base pointer (b) points to a Derived, the reference cannot be passed to Derived class pointer (d) because there's no known conversion from Base * to Derived<int> *(as what the compiler says).

我现在有一些多态问题,上面的代码总结了一切。我创建了一个基类指针,并将一个新的派生模板类的指针放入其中。然后我为派生的模板类创建了一个新指针,我希望它具有基类指针指向的引用。即使基指针 (b) 指向派生,引用也不能传递给派生类指针 (d),因为there's no known conversion from Base * to Derived<int> *(正如编译器所说)。

So is there a trick or an alternative way to be able to do it? Thanks in advance.

那么有没有技巧或替代方法可以做到这一点?提前致谢。

回答by Abrixas2

You must change the base type to be polymorphic:

您必须将基类型更改为多态:

class Base {
public:
    Base() {};
    virtual ~Base(){};
};

To cast from some supertype to some derived type, you should use dynamic_cast:

要将某些超类型转换为某些派生类型,您应该使用dynamic_cast

Base *b = new Derived<int>(1);
Derived<int> *d = dynamic_cast<Derived<int> *>(b);

Using dynamic_casthere checks that the typecast is possible. If there is no need to do that check (because the cast cannot fail), you can also use static_cast:

使用dynamic_cast此处检查类型转换是否可行。如果不需要进行该检查(因为转换不会失败),您还可以使用static_cast

Base *b = new Derived<int>(1);
Derived<int> *d = static_cast<Derived<int> *>(b);

回答by Luka Rahne

Try this:

尝试这个:

Derived<int> * d = static_cast<Derived<int>* >(b);

downside it is, that you can cast class that is instance of Base() and then d->raw() will be undefined (segmentation fault likley). If that can be case, use dynamic_cast and have at least one function ob base virtual (having destructors virtual is essential when working with polmorphism).

缺点是,您可以转换 Base() 实例的类,然后 d->raw() 将是未定义的(分段错误)。如果可以的话,请使用 dynamic_cast 并至少有一个函数 ob base virtual (在使用多态性时,析构函数 virtual 是必不可少的)。

Virtual functions are under the hood implemented using pointer on virtual table. This pointer can be also used to identify true type of class. This is used by dynamic_cast to check if this conversion can be done and brings small extra overhead when casted.

虚拟函数是在虚拟表上使用指针实现的。此指针还可用于标识类的真实类型。dynamic_cast 使用它来检查此转换是否可以完成并在转换时带来小的额外开销。

回答by Neil Kirk

You can use dynamic_cast

您可以使用 dynamic_cast

Derived<int> * d = dynamic_cast<Derived<int> *>(b);

If the cast fails (the base pointer does not point to the requested derived type), it returns null.

如果转换失败(基指针未指向请求的派生类型),则返回 null。

However, for dynamic_cast to work, your base class must have at least one virtual function. I suggest you make the destructor virtual (this is also prevents other potential problems deleting your objects).

但是,要使 dynamic_cast 起作用,您的基类必须至少有一个虚函数。我建议您将析构函数设为虚拟(这也可以防止删除对象的其他潜在问题)。

Use of dynamic_cast may indicate bad design in your code.

使用 dynamic_cast 可能表明您的代码设计不佳。

Note that if you are 100% sure the base pointer, points to your derived type, then you may replace it with static_cast, which is slightly faster. Personally I prefer the extra safety check in general.

请注意,如果您 100% 确定基指针指向您的派生类型,那么您可以将其替换为 static_cast,它会稍微快一些。我个人更喜欢一般的额外安全检查。