简体   繁体   English

试图将基数 class 指针转换为派生 class object 实现的接口

[英]Trying to cast base class pointer to a interface that derived class object implements

I am experimenting a little bit with inheritance in C++ and I stepped on a case that I don't quite understand.我在 C++ 中对 inheritance 进行了一些实验,我踩到了一个我不太明白的案例。 When I try to compile the code I get:当我尝试编译代码时,我得到:

error: cannot 'dynamic_cast' 'base' (of type 'class Base*') to type 'class SomeInterface*' (source type is not polymorphic)错误:无法将“dynamic_cast”“base”(类型为“class Base*”)键入“class SomeInterface*”(源类型不是多态的)

I assume that it is not a proper way of casting, because SomeInterface is not related to Base, but is there a way to make it work?我认为这不是正确的转换方式,因为 SomeInterface 与 Base 无关,但有没有办法让它工作? Maybe there something I can add to the class to make static_cast possible?也许我可以添加一些东西到 class 来使 static_cast 成为可能? Or is it just a bad architecture and I should rearrange my code to not introduce cases like this one?或者它只是一个糟糕的架构,我应该重新安排我的代码以不引入这样的案例? I'd appreciate any comments or resources I could read to understand this behaviour and possibly learn how to make it work.如果我能阅读任何评论或资源以了解此行为并可能了解如何使其工作,我将不胜感激。

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

dynamic_cast requires (except for up-casts) that the base class type used in the argument is polymorphic . dynamic_cast要求(向上转换除外)参数中使用的基本 class 类型是多态的。

A class in C++ is called polymorphic if it has at least one virtual function. So you need to add one to your Base , for example the destructor:如果 C++ 中的 class 至少有一个virtual function,则称为多态。因此您需要向Base添加一个,例如析构函数:

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

Polymorphic classes store additional information that is required for dynamic_cast to work at runtime.多态类存储dynamic_cast在运行时工作所需的附加信息。

However, that is a costly operation to do.然而,这是一项成本高昂的操作。 Reconsider why try_call_me is expecting a pointer to Base instead of SomeInterface if that is really what it needs.重新考虑为什么try_call_me期望指向Base而不是SomeInterface的指针,如果这确实是它所需要的。

If you keep it as it is, you also need to add error checking to the dynamic_cast .如果保持原样,您还需要向dynamic_cast添加错误检查。 It will return a null pointer if base doesn't refer to an object whose most-derived object contain a SomeInterface base class subobject that could be side-casted to:如果base不引用 object,其最衍生的 object 包含SomeInterface基 class 子对象,则它将返回一个 null 指针,该子对象可以被侧面转换为:

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 you use references instead of pointers, dynamic_cast will throw an exception instead of producing a null pointer value.) (如果您使用引用而不是指针, dynamic_cast将抛出异常而不是产生 null 指针值。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM