通过示例C++虚拟性
C++ virtuality by examples
我试图通过以下示例来理解C++中的破坏行为:https://github.com/peterdemin/virtual-destruction-5-cents
该列表是否满足了所有可能的流程?应该添加什么?如何将给定的示例转换为短期术语?
https://stackoverflow.com/a/461224/135079 提出了"当基类的析构函数要多态操作时,始终使它们成为虚拟的",这不包括场景 4。
斯科特·迈耶斯(Scott Meyers(的有效C++中的第7项指出:
- 如果一个类有任何虚函数,它应该有一个虚拟析构函数; 未
- 设计为基类或未设计为多态使用的类不应声明虚拟析构函数。
这是轻的(应该和不应该(,并且面对场景 2。
更新
我将 6502 提供的标准重写C++伪代码:
if static type of object is different from its dynamic type:
if the static type is a base class of the dynamic type:
if the static type has a virtual destructor:
We're fine - dynamic type's destructor will be called
else:
behavior is undefined [1]
else:
behavior is undefined [2]
[1] 代码将在没有警告的情况下编译,并且可能会正常工作,但不能保证,并且可能会在运行时导致纠缠错误。
[2] 这很尴尬:
class A {};
class B {};
B *a = (B*)(new A());
delete a;
当您使用基指针销毁派生对象并且析构函数不是虚拟的时,您最终会陷入"未定义的行为"场景。
N3690, 5.3.5 [删除] - 3
在第一个备选方案(删除对象(中,如果静态类型 要删除的对象不同于其动态类型,即静态 类型应是要成为的对象的动态类型的基类 已删除,静态类型应具有虚拟析构函数或 行为未定义
github存储库给出的解释是完全错误的("未调用派生析构函数,但没有发生内存泄漏"(。你不能指望这一点。
我没有阅读其余的,因为这是浪费时间。UB是UB...试图描述未定义的是无稽之谈。
当您声明方法 virtual 时,这意味着您正在指示编译器在处理派生类对象时应始终搜索方法的派生版本。就这么简单。
在下面的示例中,如果在基类方法中不使用 virtual 关键字,则将调用方法的基类版本。
#include <iostream>
class A
{
public:
virtual const char* fetchClassName() { return "A"; }
// this is a virtual destructor:
virtual ~A(){ cout<<"Destroying Base";}
};
class B: public A
{
public:
virtual const char* fetchClassName() { return "B"; }
virtual ~B(){ cout<<"Destroying Derive";}
};
int main(void)
{
B obj_b;
A &obj_a = obj_b;
std::cout << obj_a.fetchClassName() << "n";
}
相关文章:
- C++如何抛弃函数的虚拟性并调用基本函数,而不是覆盖
- C 中的多态性和虚拟
- 在多态性中重新定义功能(虚拟),具有不同数量的参数
- 具有虚拟赋值运算符的多态性
- 通过虚拟接口类导出C 类的可移植性
- 为什么我需要在子类中重新声明"虚拟"方法?[C++/多态性]
- 如果在编译时间中创建虚拟表,那么为什么我们将其称为运行时间多态性
- C++多态性/虚拟函数在此不起作用
- 方法重写(没有虚拟方法或指针)是否被认为是多态性的一部分
- c++在没有虚拟析构函数的多态性中共享ptr
- 在继承层次结构中将方法定义为虚拟方法一次,以使多态性发挥作用
- 为什么可以更改虚拟成员或公共基类的可见性
- c++多态性/纯虚拟函数
- C++:没有虚拟性的继承
- 通过示例C++虚拟性
- 函数的虚拟性行为
- C++:由于虚拟性而导致的内存开销
- 具有虚拟性的多层层次结构可以防止强制转换函数指针
- 如何模拟方法模板的虚拟性
- 派生类的成员函数是否从基类继承虚拟性?