3

参考这里

该析构函数还将隐式调用 auto_ptr 对象的析构函数。这将删除它持有的指针,该指针指向 C 对象 - 不知道 C 的定义!这出现在 .cpp 文件中,其中定义了 struct A 的构造函数。

这很好奇,然后

5.3.5/5 状态 - “如果要删除的对象在删除点具有不完整的类类型,并且完整的类具有非平凡的析构函数或释放函数,则行为未定义。”

我的问题是,为什么这样一个试图删除指向不完整类型的指针的程序不被视为格式错误?为什么它被推到有条件的领域(并且完整的类有一个非平凡的析构函数..)“未定义的行为”?

“和”是什么意思?

编辑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;
}
4

1 回答 1

5

在我写这篇文章时,您的文字说“参考 [这里] [1]”,没有参考。

但本质上,该标准允许您delete指向不完整类型的指针,以便您可以利用编译器没有的知识,即类型的析构函数什么都不做。

std::auto_ptr这是一个问题的例子,尤其是对于 PIMPL 成语(一个臭名昭著的错误例子是 Herb Sutter 在 PIMPL 上的 GOTW,他错误地使用了std::auto_ptr)。boost::shared_ptr是一个不存在问题的示例(通常)。那是因为构造函数boost::shared_ptr存储了一个删除函数,并且在构造点必须知道指针的完整类型。

干杯&hth.,

于 2010-10-18T06:09:32.233 回答