我在 C++03 标准中找到了以下代码片段5.3.5 [expr.delete] p3
:
在第一种选择(删除对象)中,如果要删除的对象的静态类型与其动态类型不同,则静态类型应为操作数动态类型的基类,并且静态类型应具有虚拟析构函数或行为未定义。在第二种选择(删除数组)中,如果要删除的对象的动态类型与其静态类型不同,则行为未定义。
快速回顾静态和动态类型:
struct B{ virtual ~B(){} };
struct D : B{};
B* p = new D();
的静态类型p
是B*
,而动态类型*p
是D
,1.3.7 [defns.dynamic.type]
:
[示例:如果
p
静态类型为“指向 ”class B
的指针指向 的对象class D
,从 派生B
,则表达式的动态类型*p
为“<code>D.”]
现在,再次查看顶部的引用,这意味着如果我做对了,下面的代码会调用未定义的行为,而不管是否存在virtual
析构函数:
struct B{ virtual ~B(){} };
struct D : B{};
B* p = new D[20];
delete [] p; // undefined behaviour here
我是否以某种方式误解了标准中的措辞?我忽略了什么吗?为什么标准将此指定为未定义的行为?