boost::scoped_ptr
documentation包含一个称为Handle / Body Idiom的技术示例。用以下词语描述:
scoped_ptr_example_test.cpp示例程序包含一个头文件, scoped_ptr_example.hpp,它使用 scoped_ptr<>到不完整的类型 隐藏实现。
然而,与此同时,在documentation for checked_delete
中声明:
一个特别麻烦的情况是智能指针的析构函数,例如 boost :: scoped_ptr :: ~scoped_ptr,用不完整的类型实例化。 这通常会导致无声,难以跟踪故障。 提供的函数和类模板可用于防止这些问题,因为它们 需要一个完整的类型,否则会导致编译错误。
scoped_ptr
确实在其实施中使用了checked_delete
。对我来说,看起来两个段落相互矛盾。此外,我无法编译我的代码,尝试使用提议的技巧,并带有以下消息:
checked_delete.hpp:32: error: invalid application of 'sizeof' to
incomplete type 'MyClass'
事实上,scoped_ptr
的文件是错误的,还是我错过了什么?
答案 0 :(得分:5)
他们互不矛盾。因为scoped_ptr
是一个模板,并且因为代码中没有明确的实例化,所以每个方法都是按需实例化的。这意味着类型必须在~scoped_ptr<>
实例化时完成,在这种情况下,在保持类型完成后在.cpp文件中(查找接近结尾的example::~example(){}
文件,这是~scoped_ptr<>
实例化的地方)
对于用户定义的析构函数来说,这实际上是一个有趣的用例,看起来与生成的编译器完全相同,但允许您在销毁时控制 / 碰巧使用一些智能指针启用PIMPL模式。如果未声明和定义析构函数,那么析构函数将由编译器在需要时隐式定义,并且类型将不完整,从而导致UB。
答案 1 :(得分:2)
类模板的成员函数仅在实例化的位置实例化
用过的。在ins中使用唯一的地方boost::scoped_ptr::~scoped_ptr
example
的析构函数。其中定义了
scoped_ptr_example.cpp
,定义之后
example::implementation
已完成。功能
boost::checked_delete
的设计是为了在编译时不会编译
类型不完整; boost::scoped_ptr::~scoped_ptr
使用了这个
如果您尝试在上下文中调用它,代码将无法编译
类型不完整。
(FWIW:在pimpl成语中使用boost::scoped_ptr
有点矫枉过正,
而且不是很有用;因为您必须提供用户定义的析构函数
无论如何,它真的不会给你带来太大的收益,并且增加了一点点
复杂性。)