是否可以从一个基类到另一个基类进行dynamic_cast?

Ale*_*lex 5 c++ inheritance dynamic-cast class

例如,我有这样的代码

class Base1
{
  virtual void wonderFULL() = 0;
};

class Base2
{
  // all this weird members
};

class Derived : public Base1, public Base2
{
  // not so weird members
};

int main()
{
  Derived Wonder;
  magicFunction(&Wonder);
  return 0;
}

void magicFunction(Base2 *ptr)
{
  if (Base1 *b1 = dynamic_cast<Base1 *>(ptr))
    b1->wonderFULL();
}
Run Code Online (Sandbox Code Playgroud)

但是,由于不可能将ptr转换为b1,所以neverFULL永远不会被执行.是否有可能进行这样的转换?

sbi*_*sbi 7

这个

#include <iostream>

class Base1 {
public:
    virtual void wonderFULL() = 0;
};

class Base2 {
public:
    virtual ~Base2() {}                                       // added so the code compiles
};

class Derived : public Base1, public Base2 {
    virtual void wonderFULL() {std::cout << "wonderful\n";}   // added so the code compiles
};

void magicFunction(Base2 *ptr) {
    if (Base1 *b1 = dynamic_cast<Base1 *>(ptr))
        b1->wonderFULL();
}

int main() {
    Derived Wonder;
    magicFunction(&Wonder);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

打印wonderful给我.我的结论是,您没有显示重现问题所需的代码.

获取(副本)您的实际代码,并逐步删除不必要的代码,直到您获得自包含(除std lib之外不需要其他标题),再现问题的可编译示例.这样做很可能会发现问题.但是,如果你不这样做,你就有了完美的复制案例,可以回到这里询问一下.


Dae*_*min 0

根据我对某些 C++ 编译器在内存中排列类层次结构的理解,应该可以从一个基类转换为另一个基类,但必须首先转换为派生类。

因此,您需要执行以下操作:

Base1* b1 = dynamic_cast<Derived*>(ptr);
Run Code Online (Sandbox Code Playgroud)

这会将给定的指针强制转换ptr为派生类,然后将其隐式强制转换为其另一个基类指针。

然而,另一种更简单的方法是在 Base2 类中拥有一个返回 Base1 指针的方法,并且派生类可以自行实现此方法,而无需任何棘手的代码。(如果您不需要纯虚拟类,Base2 中的相同函数可以只返回 NULL)。