C++ c++;在运行时检查对象是否实现了接口

C++ c++;在运行时检查对象是否实现了接口,c++,casting,multiple-inheritance,C++,Casting,Multiple Inheritance,前段时间我问过这些问题: 但我仍然不确定我是否理解答案问题是:下面的代码有效吗? #include <iostream> using namespace std; struct Base { virtual void printName() { cout << "Base" << endl; } }; struct Interface { virtual void foo() {

前段时间我问过这些问题:

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

#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;
}
#包括
使用名称空间std;
结构基
{
虚拟void printName()
{

cout如果
dynamic\u cast
成功,则它是有效的。它已在运行时执行类型安全检查。

它是有效的代码

为什么?
因为
dynamic\u cast
会告诉您所指向的对象实际上是否属于您要强制转换的类型。

在这种情况下,所指向的实际对象是
派生的
类型,而
派生的
类型的每个对象也是
接口的
(因为
派生的
继承自
接口
)因此,
dynamic\u cast
是有效的,它可以工作。

只要所涉及的类至少有一个虚拟方法(可以是虚拟析构函数),使用
dynamic\u cast
是正确的,并且可以在一致的编译器上工作

static\u cast
不同,
dynamic\u cast
允许运行时检查类型信息。但是,这也意味着它可能会失败,并在使用它来转换指针时返回一个
NULL
。如果转换结果可能不成功,则应检查转换结果


在您提出的上一个问题中,这些类没有任何虚拟方法,因此无法工作,因为
dynamic\u cast
不能用于此类类。

请考虑以下几点:

Base *b = new B();
Interface *i = dynamic_cast<Interface *>( b );
Base*b=新的b();
接口*i=动态_-cast(b);

应该这样做吗?不。为什么?因为
Base
Interface
彼此不相关。但是,在特殊情况下,指向
Base
的指针指向同样从
Interface
派生的对象时,可以强制转换(阅读:诱使编译器将对象视为
接口
)类型的
指针,并进一步使用
动态转换
运算符的结果。

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

运行时检查按如下逻辑执行:

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

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

-否则,运行时检查将失败


请注意在运行时检查中使用“最派生的对象”。在您的示例中,“最派生的对象”对于您的
Base*b
对象是一个
派生的
对象。由于类
派生的
公开继承自
Base
接口
,在这种特殊情况下,
Base*
对象可以转换为
接口*

答案中的注释对于您前面的问题,请务必说明
动态\u cast
将在您的案例中起作用。虽然在本例中恰好是这样,但我不想开创“如果它起作用,它就是正确的”的先例因为它是动态的,所以这就是论点。我不想再解释上10多个众所周知的问题SO@UmNyobe:OP的问题是它为什么有效?答案不是因为
dynamic\u cast
这么说。他已经知道
dynamic\u cast
这么说了(OP展示了一个精心制作的示例代码来演示它)真正的问题是为什么
dynamic\u cast
有效?与我前面的问题有什么区别?(真的不明白)@安德鲁:没有区别,埃米利奥·加拉瓦格利亚在上一个问题中给了你同样的答案。@安德鲁:
dynamic\u cast
只有在类(也称多态类)中至少有一个
virtual
方法时才有效。请参阅。您之前的示例没有任何
virtual
方法,因此无法使用
dynamic\u-cast
。我是否理解dynamic\u-cast中涉及的所有类都必须是多态的?安德鲁:是的。如果基类是多态的,则所有派生类也将是多态的。您只需要一个
virtual
methodo它甚至可以是一个析构函数。