参考here
析构函数也会隐式 调用auto_ptr的析构函数 宾语。这将删除 它持有的指针,指向C 对象 - 不知道 C的定义!那出现在 .cpp文件,其中struct A的构造函数 是定义。
这很奇怪然后
5.3.5 / 5状态 - “如果要删除的对象具有不完整的类类型,则为 删除点和完整 class有一个非平凡的析构函数或 一个解除分配函数,行为 未定义。“
我的问题是,为什么不是这样的程序试图删除指向不完整类型的指针被视为格式错误?为什么它被推入条件领域(和完整的类有一个非平凡的析构函数......)'未定义的行为'?
“和”意味着什么?
编辑2:
下面的代码是否格式正确? VS和Gcc / CLang编译,但是Comeau发出警告。我想这一切都是标准中提到的未定义行为的一部分。我的问题是“为什么这不是形成错误但是未定义”?
#include <iostream>
#include <memory>
using namespace std;
struct C;
// Is this the POI for auto_ptr<C>? $14.6.4.1/3
struct A{
A();
auto_ptr<C> mc;
~A(){} // how does it link to C::~C at this point?
};
struct C{};
A::A():mc(new C){}
int main(){
A a;
}
答案 0 :(得分:5)
在我写这篇文章时,你的文字说“参考[这里] [1]”没有参考。
但实质上,该标准允许您delete
指向不完整类型的指针,以便您可以利用编译器不具备的知识,即类型的析构函数不执行任何操作。
std::auto_ptr
是一个例子,这是一个问题,特别是对于PIMPL习语(一个臭名昭着的错误例子是Herb Sutter在PIMPL上的GOTW,他错误地使用了std::auto_ptr
)。 boost::shared_ptr
是一个不存在问题的例子(一般情况下)。那是因为boost::shared_ptr
的构造函数存储了一个删除函数,并且必须在构造点知道指针的完整类型。
干杯&amp;第h。,