如果对象实现接口,则在运行时检查c ++

时间:2012-05-01 16:31:18

标签: c++ casting multiple-inheritance

我前段时间问过这个问题: 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;
}

代码可以按我的意愿运行。但据我所知,根据之前的问题,它不应该。所以我不确定这些代码是否有效。谢谢!

5 个答案:

答案 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 );

这应该有用吗?不。为什么,因为BaseInterface彼此无关。但是,在指向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对象。由于课程DerivedBaseInterface公开继承,因此在此特定情况下,Base*对象可以投放到Interface*

相关问题