如何使用非多态基类进行向下转型

5
在C++中,如果我没有将析构函数声明为虚函数,是否仍然可以将非多态基类的指针/引用向下转换?

那么,如果我的基类是非多态的(没有虚方法/析构函数),我不能进行向下转型,这种说法正确吗? - Adrika
使用 dynamic_cast 是不可能的。 - Some programmer dude
我不想使用组合,而是在探索继承。使用 static_cast/ reinterpret_cast 只能进行编译时检查。我的代码仍然可能在运行时崩溃,因为 static/reinterpret cast 仍然允许坏的指针/引用通过。因此,可以安全地假设,如果我想将 Base * bptr 向下转换为 Derived * dptr(所有非多态),我总是处于坏指针/坏引用的风险中。(除非我使用虚析构函数) - Adrika
如果你遇到崩溃,请考虑询问与之相关的问题。请先参加SO之旅,然后阅读如何提出好问题的指南,最后请学习如何创建最小、完整和可验证示例 - Some programmer dude
我试图回答,但软件说“不”不够多字符。 - Jive Dadson
显示剩余3条评论
1个回答

2

虚拟析构函数与向下转型关系不大。将析构函数设为虚拟的目的是为了通过基类指针安全删除对象。

Base * ptr = new Derived;
delete ptr; // undefined behavior if Base destructor isn't virtual

可以使用static_cast进行向下转型,但需自行承担责任。

void processBase(Base * ptr)
{
    // undefined behavior if ptr does not point to Derived
    // object or some object that inherits from Derived
    Derived * derived = static_cast<Derived *>(ptr);
}

此外,还有dynamic_cast,它将检查向下转型是否合法,但需要转型的表达式指向(或引用)一个多态对象(即至少声明或继承一个虚函数的对象)。

5.2.7.6否则,v应为多态类型的指针或左值(10.3)

如果转型表达式的类型不是多态的,则程序将无法编译。

总结一下 - 使析构函数为虚函数将使您的类变成多态类,但声明任何其他虚成员函数也会实现相同的效果。要使用dynamic_cast,您需要一个多态类型。


在非多态类型上进行 dynamic_cast 向下转换是不合法的。 - Oktalist
这意味着我在理解标准措辞方面存在问题。因为在这个部分中使用了“v具有指向cv2 D的指针类型”的短语,而在这个部分中区分表达式类型和指向对象类型非常重要,所以我认为要求是指完整的指针类型。然而,ideone拒绝非多态表达式类型,所以你是正确的。 - Tadeusz Kopec for Ukraine

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接