c++ 尝试将基类指针强制转换为派生类对象实现的接口

svdrlsy4  于 2023-02-06  发布在  其他
关注(0)|答案(1)|浏览(187)

我在C++中做了一些继承的实验,遇到了一个我不太理解的情况,当我试图编译代码时,我得到:
错误:无法将“base”(类型为“class Base ”)“dynamic_cast”为类型“class SomeInterface”(源类型不是多态的)
我认为这不是一种正确的强制转换方式,因为SomeInterface与Base无关,但是有没有办法让它工作呢?也许我可以在类中添加一些东西来使static_cast成为可能呢?或者它只是一个糟糕的架构,我应该重新安排我的代码来避免引入像这样的情况呢?我'我很感激任何评论或资源,我可以阅读,以了解这种行为,并可能学习如何使它的工作。

class Base
{
    
};

class SomeInterface
{
    
public:
    void call_me() { }
};

class Derived : public Base, public SomeInterface
{

};

void try_call_me(Base* base)
{
    // line below causes an error
    SomeInterface* some_interface_instance = dynamic_cast<SomeInterface*>(base);
    some_interface_instance->call_me();
}

int main()
{
    Derived derived_instance;
    Base* base_instance = &derived_instance;
    
    try_call_me(base_instance);
    return 0;
}
oxiaedzo

oxiaedzo1#

dynamic_cast要求参数中使用的基类类型为 polymorphic(向上强制转换除外)。
在C++中,如果一个类至少有一个virtual函数,那么这个类就叫做 polymorphic,所以你需要在你的Base中添加一个函数,比如析构函数:

struct Base
{
    virtual ~Base() = default;
};

多态类存储dynamic_cast在运行时工作所需的附加信息。
但是,这是一个代价高昂的操作。如果try_call_me确实需要Base而不是SomeInterface,请重新考虑为什么try_call_me需要指向Base的指针。
如果你保持不变,你还需要在dynamic_cast中添加错误检查,如果base没有引用一个对象,而该对象的最大派生对象包含一个可以侧转型的SomeInterface基类子对象,那么dynamic_cast将返回一个空指针:

SomeInterface* some_interface_instance = dynamic_cast<SomeInterface*>(base);
if(!some_interface_instance) {
    // didn't pass a suitable pointer, error!
    // fail here, otherwise there will be undefined behavior!
} else {
    some_interface_instance->call_me();
}

(If使用引用而不是指针,dynamic_cast将抛出异常而不是生成空指针值。)

相关问题