Per*_*-lk 3 c++ raii unique-ptr raw-pointer
当您将 a 用于unique_ptr<T>前向声明的类型时T,unique_ptr析构函数要求 theT是完整的,但还需要移动赋值运算符(和reset),根据此表:
因此,对于您的pImpl习惯用法,要正确实现它,您必须声明 thedelete和 the move assignment method(这作为副作用,将它们标记为非内联):
class impl_t;
class A
{
std::unique_ptr<impl_t> p_impl;
public:
// Implement in A.cpp as A::~A() = default;
~A();
// Implemented in A.cpp as A& operator=(A&&) = default;
A& operator=(A&& he);
};
Run Code Online (Sandbox Code Playgroud)
但是,由于std::unique_ptr是动态内存的 RAII 解决方案,并且您pImpl已经在一个类中,并且无论如何您都被迫编写析构函数,因此管理原始指针不是更好吗,因为您的类已经是 RAII-就像从 ? 的角度来看p_impl:
class impl_t;
class A
{
impl_t* p_impl;
public:
~A(); // The destructor must be written anyway.
// The omitted move assignment destructor doesn't cause UB.
};
Run Code Online (Sandbox Code Playgroud)
这不是更好的解决方案吗?(如果您想要类可复制/可移动,则定义或删除您自己的复制/移动运算符;但这是一个“有意识的选择”;但是,不要为其编写移动赋值unique_ptr是一个错误)。
使用 a only 可以节省您在无论如何都必须声明的析构函数中unique_ptr编写 a 的麻烦。delete p_impl
unique_ptr对于本地动态对象来说,这是一个很好的选择,即使在出现异常的情况下,它也会被破坏,但是对于“属性”来说,如果您不记得必须重写移动赋值运算符,除了获得 UB 的可能性之外,您什么也没有保存。
好吧,使用 a可以让您免于为的std::unique_ptr显式操作而烦恼。deletep_impl
此外,它应该在并发访问和构造函数中的异常情况下运行良好(这似乎不能保证使用原始指针和new您自己)。
| 归档时间: |
|
| 查看次数: |
717 次 |
| 最近记录: |