这个枚举在析构函数中有什么作用?

14
// Destructor.  If there is a C object, delete it.
// We don't need to test ptr_ == NULL because C++ does that for us  

    ~scoped_ptr() {
       enum { type_must_be_complete = sizeof(C) };
       delete ptr_;
    }

注意:C是一个模板参数
我知道我们不能删除一个空指针,否则会引发异常。所以在这种情况下,枚举定义必须做一些防止这种情况的事情。在生产中,有时我们不想仅仅因为有一个空指针而结束程序,我们可能希望查看替代方案,当指针为空时。这段代码在生产中几乎无处不在吗?
谢谢大家。

7
我们可以删除一个空指针,这样做是完全有效的。 - Alok Save
我认为我的问题是指针的双重删除混淆了。当编译器检测到双重删除时,它总是会引发异常。那么删除空指针和双重删除之间有什么区别呢? - maress
2
@maress:你可以尝试删除一个空指针多次(实际上,你可以尝试删除它,运行时会检测到空指针并不执行任何操作)。 - rjnilsson
1
当你在指针上应用 delete 时,它会删除指向的对象,并将内存返回给运行时,但是指针本身仍然保持不变。如果您再次应用 delete,它将访问属于运行时而不是应用代码的内存,并且不再包含“活动”对象...这会带来麻烦。另一方面,空指针不指向任何地方,因此在尝试访问所指向的内存之前,delete 的实现应该检查此条件。 - Matthieu M.
2个回答

17

这实际上是用于删除的静态断言。实现想知道它是否正在处理一个在删除变量之前声明可见的类型,而不是一个前向声明。

当您尝试获取一个不完整类型的大小时,编译器将会报错:

struct S;
enum { Size = sizeof(S) };

更新

正如您的编译器和Matthieu M.所指出的那样,delete一个不完整的类型是未定义的。


2
@sharptooth:我认为C更加清晰,而且打起来也更快 :) - Matthieu M.
5
@Justin: 值得说明的是,尝试删除指向不完整类型的指针是未定义行为,因此值得诊断。Boost库也有相同效果的checked_delete,他们本可以重复利用它,但可能觉得这并不需要特定的包含文件,因此没有这样做。 - Matthieu M.
@sharptooth 我现在想不出一个好理由 - 有吗? - justin
@Matthieu M.:我不认为这样更清晰。如果 _ptr 的类型以后改变了呢?那么 C 也应该被修改,但编译器并不会关心。 - sharptooth
@sharptooth:我说的不是 cleaNer 而是 cleaRersizeof(C) 有非常明确的含义,而 sizeof(*ptr_) 则不太清晰。至少我的同事们对未求值的操作数并不太熟悉。 - Matthieu M.

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接