我前段时间问过这个问题: Multiple inheritance casting from base class to different derived class
但我仍然不确定我理解答案。 问题是:以下代码是否有效?
#include <iostream>
using namespace std;
struct Base
{
virtual void printName()
{
cout << "Base" << endl;
}
};
struct Interface
{
virtual void foo()
{
cout << "Foo function" << endl;
}
};
struct Derived : public Base, public Interface
{
virtual void printName()
{
cout << "Derived" << endl;
}
};
int main(int argc, const char * argv[])
{
Base *b = new Derived();
Interface *i = dynamic_cast<Interface*>(b);
i->foo();
return 0;
}
代码可以按我的意愿运行。但据我所知,根据之前的问题,它不应该。所以我不确定这些代码是否有效。谢谢!
答案 0 :(得分:4)
这是有效的代码。
<强>为什么吗
因为dynamic_cast
告诉您指向的对象是否实际上是您要转换的类型
在这种情况下,指向的实际对象属于Derived
类型,类型Derived
的每个对象也属于Interface
类型(因为Derived
继承自Interface
1}})因此dynamic_cast
有效且有效。
答案 1 :(得分:2)
只要涉及的类至少有一个虚方法(可能是虚析构函数),使用dynamic_cast
就可以了,并且可以在符合标准的编译器上运行。
与static_cast
不同,dynamic_cast
可以允许运行时检查类型信息。但是,这也意味着它可能会失败,并在使用它来转换指针时返回NULL
。如果有可能不成功,应检查演员表。
在您提出的上一个问题中,这些类没有任何虚拟方法,因此不起作用,因为dynamic_cast
不能在这样的类上使用。
答案 2 :(得分:0)
如果dynamic_cast
成功,那么它就是有效的。它已经在运行时执行了类型安全检查。
答案 3 :(得分:0)
请考虑以下事项:
Base *b = new B();
Interface *i = dynamic_cast<Interface *>( b );
这应该有用吗?不。为什么,因为Base
和Interface
彼此无关。但是,在指向Base
的指针指向同样派生自Interface
的对象的特殊情况下,您可以强制转换(读取:哄骗编译器将对象视为类型{{1} }}} Interface
指针并进一步使用Base
运算符的结果。
答案 4 :(得分:0)
您的代码是有效的,因为标准在5.2.7第4段(C ++ 2003标准)中这样说:
运行时检查按逻辑执行如下:
- 如果在由v指向(引用)的大多数派生对象中,v指向(引用)T对象的公共基类子对象,并且如果只有一个T类型的对象派生自该子对象-object指向(引用)v,结果是指向该T对象的指针(左值引用)。
- 否则,如果v指向(引用)最派生对象的公共基类子对象,并且最派生对象的类型具有类型为T的基类,即明确且公开的,则result是指向最派生对象的T子对象的指针(左值引用)。
- 否则,运行时检查失败。
请注意在运行时检查中使用“大多数派生对象”。在您的示例中,Base *b
对象的“派生程度最高的对象”是Derived
对象。由于课程Derived
从Base
和Interface
公开继承,因此在此特定情况下,Base*
对象可以投放到Interface*
。