要了解enum
,请首先考虑不带的析构函数:
~scoped_ptr() {
delete ptr_;
}
哪里ptr_
是C*
。如果此时的typeC
不完整,即编译器知道的全部是struct C;
,则(1)将默认生成的空做什么析构函数用于所指向的C实例。对于由智能指针管理的对象,这不太可能是正确的选择。
如果通过指向不完整类型的指针进行删除始终具有未定义行为,则该标准可能仅要求编译器对其进行诊断并失败。但是,当真正的析构函数是微不足道的时,它是明确定义的:程序员可以拥有而编译器没有的知识。语言为什么定义并允许这样做,这超出了我的范围,但是C ++支持许多今天不被视为最佳实践的实践。
完整类型具有已知的大小,因此,sizeof(C)
当且仅当C
是完整类型(具有已知析构函数)时,才会编译。因此它可以用作警卫。一种方法就是简单
(void) sizeof(C);
我猜想,使用某些编译器和选项,编译器会在对其不应该进行编译之前进行优化,enum
从而避免了这种不符合规范的编译器行为:
enum { type_must_be_complete = sizeof(C) };
选择enum
不只是丢弃的表达方式的另一种解释就是个人喜好。
或正如James T. Hugget在对此答案的评论中所建议的那样: “枚举可能是在编译时创建伪便携式错误消息的一种方式”。
(1)对于不完整类型,默认生成的空做什么析构函数是old的问题std::auto_ptr
。它是如此阴险,以至于它进入了国际C ++标准化委员会主席赫伯·萨特(Herb Sutter)撰写的有关PIMPL习惯用语的GOTW项目中。当然,在如今std::auto_ptr
已弃用的情况下,将改为使用其他某种机制。
ptr_
自己的sizeof
作为sizeof(*ptr_)
,而不是sizeof(C)
。