在Herb Sutter在CppCon16上的演讲中,他建议使用 const std::unique_ptr
编写pimpl习惯用语(大约在10分钟处)。
在移动构造函数/赋值时,这应该如何工作?在C++17中是否有任何东西?我找不到任何消息。
在Herb Sutter在CppCon16上的演讲中,他建议使用 const std::unique_ptr
编写pimpl习惯用语(大约在10分钟处)。
在移动构造函数/赋值时,这应该如何工作?在C++17中是否有任何东西?我找不到任何消息。
std::move
的精神相悖。 - Richard Hodgesconst unique ptr
,您的对象无法移动,此问题不会出现。通过使用特定的 never_empty_ptr
,您的代码永远不可能为空,此问题也不会发生。另一方面,手动将永不为空的状态插入类中可能是一个坏主意。 - Yakk - Adam Nevraumontstd::move
”约束,以限制(可能是次标准的)开发人员。当然,所有优秀的开发人员一旦找到更好的工作就会离开,但您仍然可以保证您的“永不为空”的保证,同时允许其他团队编写高效的代码。我很难想象出一个合理的使用场景来解释这个习语。它一下子就抵消了从c++03升级到c++11所带来的90%的巨大效用和性能增量。 - Richard Hodgesstd::move
,因为每个C++标准容器在移动后都表现得非常合理(除了移动分配),而且您编写的每种类型也可以在移动后表现得合理。有些对象可能是“有时为空”(例如unique ptr),但对于它们,所有使用它们的地方都需要进行保护。很少使用“几乎从不为空”的类型,因为它们会鼓励您假设它们永远不为空,而当它们为空时会发生灾难性的错误。这种观点中的问题在于“几乎从不为空”的类型,而不是std::move
。或者编写您的移动空类型以在所有操作上自动填充。 - Yakk - Adam Nevraumontconst std::unique_ptr
是这样的数据成员。const
,编译器将生成移动构造函数和赋值操作符,但不会生成复制构造函数。const unique_ptr
:const
成员更加健壮,因为const
成员必须在构造函数中初始化。而且const
说明对象的实现不会改变,它不是状态或策略设计模式。std::unique_ptr
上std::move
的默认行为是绝对正确的,也是我们想要的——高效的状态转移,使经过移动的句柄处于一个非常明确定义的状态——“无效,请勿操作”。显式禁用移动是一回事(人们可能会对动机产生疑问),通过使用const进行神秘的禁用只是看起来像是一种嬉戏。 - Richard HodgesMyClass& operator=(const MyClass& that) { *pimpl = *that.pimpl; return *this; }
。Impl
类仍然可以复制甚至可移动,您可以委托给它。当然,这只能让您完成95%的工作,并且也可以编写自己的 value_ptr
类型,以自动执行深层复制/移动。 - Herb Sutter
unique_ptr
作为pimpl的容器。如果你想让它可复制,当然必须通过克隆操作来实现。 - Richard Hodgesconst unique_ptr
很快就会成为一种限制。 - Richard Hodges