例如,我有类似的代码
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,所以neverFULL永远不会被执行。是否有可能进行这样的转换?
答案 0 :(得分: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之外不需要其他标题),再现问题的可编译示例。这样做很可能会发现问题。但是,如果你不这样做,你就有了完美的复制案例,可以回到这里询问一下。
答案 1 :(得分: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 */ }
}
答案 2 :(得分:2)
您有一些语法错误,但如果您的基类没有至少一个虚函数,那么您的真正问题是dynamic_cast
将无法正常工作。
如果你看起来像:
class Base2
{
public:
virtual ~Base2() {}
// all this weird members
};
然后修复您的其他错误:
wonderFULL
是私有的,从未定义过。
magicFunction
在使用后声明。
然后一切works。
答案 3 :(得分:0)
按照我对一些C ++编译器在内存中排列类层次结构的理解,应该可以从一个基类转换到另一个基类,但是你必须首先转换为派生类。
因此,您需要执行以下操作:
Base1* b1 = dynamic_cast<Derived*>(ptr);
这会将给定指针ptr
强制转换为派生类,然后将其隐式强制转换为其他基类指针。
然而,另一种更简单的方法是在Base2类中只有一个返回Base1指针的方法,派生类本身可以实现它,而不需要任何棘手的代码。 (如果您不想要纯虚拟类,Base2中的相同函数只能返回NULL。)
答案 4 :(得分:0)
我发现了问题。这不是关于dynamic_casts。我正在检查错误的对象,它不是从抽象基础继承的。感谢。