4

我前段时间问过这些问题: 从基类到不同派生类的多重继承转换

但我仍然不确定我是否理解答案。问题是:下面的代码有效吗?

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

代码按我的意愿工作。但据我了解,根据前面的问题,它不应该。所以我不确定这样的代码是否有效。谢谢!

4

5 回答 5

5

这是有效的代码。

为什么?
因为dynamic_cast告诉您所指向的对象是否实际上是您要转换的类型。
在这种情况下,指向的实际对象是类型,并且该类型的Derived每个对象Derived也是类型Interface(因为Derived继承自Interface),因此它dynamic_cast是有效的并且它有效。

于 2012-05-01T16:38:40.593 回答
3

只要所涉及的类至少有一个虚拟方法(可能是虚拟析构函数),dynamic_cast按原样使用就是正确的,并且可以在符合标准的编译器上工作。

与 不同static_castdynamic_cast可以允许对类型信息进行运行时检查。但是,这也意味着它可能会失败,并NULL在使用它来转换指针时返回 a。如果有任何可能不成功,则应检查转换结果。

在您问的上一个问题中,这些类没有任何虚拟方法,因此无法工作,因为dynamic_cast不能在这样的类上使用。

于 2012-05-01T16:39:00.980 回答
0

您的代码是有效的,因为标准在 5.2.7 第 4 段(C++ 2003 标准)中这样说:

运行时检查在逻辑上执行如下:

— 如果在 v 指向(引用)的最派生对象中,v 指向(引用)一个 T 对象的公共基类子对象,并且如果只有一个 T 类型的对象是从所指向的子对象派生的(引用)由 v 引用,结果是指向该 T 对象的指针(左值引用)。

— 否则,如果 v 指向(引用)最派生对象的公共基类子对象,并且最派生对象的类型具有类型 T 的明确且公共的基类,则结果为指向最派生对象的 T 子对象的指针(左值引用)。

— 否则,运行时检查失败。

请注意在运行时检查中使用“大多数派生对象”。在您的示例中,您的对象的“最衍生对象”Base *b是一个Derived对象。由于类Derived从两者公开继承Baseand ,在这种特殊情况下Interface,该Base*对象可以强制转换为 a 。Interface*

于 2012-05-01T16:45:29.667 回答
0

如果dynamic_cast成功则有效。它已经在运行时执行了类型安全检查。

于 2012-05-01T16:36:29.093 回答
0

考虑以下:

Base *b = new B();
Interface *i = dynamic_cast<Interface *>( b );

这应该工作吗?不,为什么,因为BaseInterface彼此无关。Base但是,在指针指向一个对象的特殊情况下,Interface您可以强制转换(阅读:诱使编译器考虑对象是 type InterfaceBase指针并dynamic_cast进一步使用运算符的结果。

于 2012-05-01T16:40:00.063 回答