5

例如我有这样的代码

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();
}

然而,由于无法将 ptr 转换为 b1,wonderFULL 从未执行过。是否有可能执行这样的转换?

4

5 回答 5

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

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

获取(副本)您的实际代码,并通过逐步删除不必要的代码来提取它,直到您导出一个独立的(除了来自 std lib 之外不需要其他头文件),重现问题的可编译示例。这样做时您很可能会发现问题。但是,如果你不这样做,你有一个完美的复制案例可以回到这里询问。

于 2010-09-28T14:00:27.567 回答
2

您可以向上转换层次结构,然后再向下转换:

void magicFunction(Base2& ptr)
{
    try
    {
        Derived&  d = dynamic_cast<Derived&>(ptr);
        Base1&    b = dynamic_cast<Base1&>(d);
        b.wonderFULL();
    }
    catch(const std::bad_cast&)
    { /* Cast failed */ }
}
于 2010-09-28T14:00:36.843 回答
2

你有一些语法错误,但dynamic_cast如果你的基类没有至少一个虚函数,你的真正问题是无法正常工作。

如果你让它看起来像:

class Base2
{
public:
  virtual ~Base2() {}
  // all this weird members
};

然后修复您的其他错误: wonderFULL是私有的,从未定义过。 magicFunction在使用后声明。

然后一切正常

于 2010-09-28T14:10:23.110 回答
0

Going by what I understand of the way some C++ compilers arrange the class hierarchy in memory it should be possible to cast from one base class to another, but you have to first cast to the derived class.

Therefore you would need to do something like:

Base1* b1 = dynamic_cast<Derived*>(ptr);

This casts the given pointer ptr to the derived class, and then it gets implicitly cast to its other base class pointer.

However another easier way to do this would be to just have a method in the Base2 class that returns a Base1 pointer, and the derived class can implement this itself without any tricky code. (The same function in Base2 can just return NULL if you don't want a pure virtual class).

于 2010-09-28T13:59:22.240 回答
0

我发现了问题。这与 dynamic_casts 无关。我正在检查不是从抽象基础继承的错误对象。谢谢。

于 2010-09-28T14:15:10.837 回答