我在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]
:
[示例:如果一个静态类型为“指向类 B 的指针”的指针
p
指向一个派生自B
的类D
的对象,则表达式*p
的动态类型为 “D
”。]
现在再次查看顶部的引用,这意味着如果我理解正确的话,以下代码将调用未定义的行为,无论是否存在 virtual
析构函数:
struct B{ virtual ~B(){} };
struct D : B{};
B* p = new D[20];
delete [] p; // undefined behaviour here
我是否误解了标准中的措辞?我有没有忽略什么?为什么标准将这种情况指定为未定义行为?
(vector<B*> v(N)) == (B* p = new B[N])
联系在了一起。没有这个,这个问题现在完全没有意义。:| - Xeo