不能因为类不是多态而沮丧吗?

2021-12-17 00:00:00 inheritance polymorphism c++ vtable

是否可以在没有虚方法的情况下进行继承?编译器说下面的代码不是多态的.

Is it possible to have inheritance with no virtual methods? The compiler is saying that the following code is not polymorphic.

示例:

class A {
public:
    int a;
    int getA(){return a;};
}


class B : public A {
public:
    int b;
    int getB(){return b;};
}

在另一个类中,我们试图从 A 对象向下转换为 B 对象:

In another class we are trying to downcast from an A object to a B object:

 A *a = ...;
 B *b = dynamic_cast<B*>(a)

但这会导致以下编译时错误:

but this gives the following compile-time error:

 cannot dynamic_cast ... (source type is not polymorphic)

推荐答案

语法错误,您不能dynamic_cast 非多态类型.static_cast 是您将在这种情况下使用的强制转换,如果您知道它实际上是目标类型的对象.

Syntax errors non-withstanding, you cannot dynamic_cast a non-polymorphic type. static_cast is the cast you would use in this case, if you know that it is in fact an object of the target type.

原因:static_cast 基本上是让编译器在编译时执行检查输入是否可以强制转换为输出?"这可用于向上或向下转换指针(或引用)的继承层次结构的情况.但检查仅在编译时进行,编译器假定您知道自己在做什么.

The reason why: static_cast basically has the compiler perform a check at compile time "Could the input be cast to the output?" This is can be used for cases where you are casting up or down an inheritance hierarchy of pointers (or references). But the check is only at compile time, and the compiler assumes you know what you are doing.

dynamic_cast 只能在指针或引用强制转换的情况下使用,并且除了编译时检查之外,它还会进行额外的运行时检查以确保强制转换是否合法.它要求有问题的类至少有 1 个虚方法,这允许编译器(如果它支持 RTTI)执行这个额外的检查.但是,如果所讨论的类型没有任何虚方法,则无法使用.

dynamic_cast can only be used in the case of a pointer or reference cast, and in addition to the compile time check, it does an additional run time check that the cast is legal. It requires that the class in question have at least 1 virtual method, which allows the compiler (if it supports RTTI) to perform this additional check. However, if the type in question does not have any virtual methods, then it cannot be used.

最简单的情况,如果你像这样传递指针可能是值得的,就是考虑使基类的析构函数成为虚拟的.除了允许您使用动态转换之外,它还允许在删除基类指针时调用适当的析构函数.

The simplest case, and probably worthwhile if you're passing pointers around like this, is to consider making the base class's destructor virtual. In addition to allowing you to use dynamic cast, it also allows the proper destructors to be called when a base class pointer is deleted.

相关文章