【发布时间】:2022-01-09 02:04:39
【问题描述】:
AFAIK unique_ptr 与 PIMPL 一起使用非常棘手,因为删除器是 unique_ptr 类型的一部分,因此它不适用于不完整的类型。另一方面,shared_ptr 使用动态删除器,因此它适用于不完整的类型。
shared_ptr 存在性能问题,无论我是否需要,都给我一个原子操作。
std:: 中还有其他更快的替代方案吗?我显然对类型擦除很好,我说的是原子引用计数的成本。
#include <any>
#include <memory>
#include <iosfwd>
std::shared_ptr<std::fstream> sp;
// unique_ptr requires complete type
// std::unique_ptr<std::fstream> up;
std::any a;
#include <fstream>
int main() {
// any requires copy_constructible
// a = std::fstream{};
sp = std::make_shared<std::fstream>();
}
注释:
- 我考虑过
any,但它不适用于某些类型。 - 我认为 unique_ptr 带有动态删除器,但 AFAIK
unique_ptr构造函数永远不会“告诉”删除器构造的对象是什么(为删除器提供学习如何销毁对象的方法)。
附:我很久以前就知道boost::shared_ptr 有宏来禁用原子引用计数,但即使仍然支持它我也不想切换到boost::shared_ptr。
【问题讨论】:
-
AFAIK unique_ptr is quite tricky to use with PIMPL如何定义棘手?只需在头文件中声明需要知道完整类型的析构函数和方法,并在定义不完整类型的地方使用= default(C++ Pimpl Idiom Incomplete Type using std::unique_ptr)进行定义 -
对于这个问题的棘手定义:我不能只包含 fwd 声明头并编写“正常”(除了我必须使用指针,而不是值)代码,我需要制作一个助手构建自己。
-
我不完全理解这个问题或你对
(beside the fact I must use pointers, not values) code, I need to make a helper struct myself.的意思。以下代码有什么问题?/*header*/struct Type { Type(); ~Type(); struct TypeImpl; std::unique_ptr<TypeImpl> impl }; /*source*/ struct TypeImpl{}; Type::Type() : impl(new Type::TypeImpl()) {} Type::~Type() = default; -
@t.niese 注意,如果您希望它是可移动的,我相信您还必须明确添加移动操作符,因为用户定义的析构函数仍然禁止移动操作。但是我之前已经多次按照您的建议进行过,并且确实有效。
-
@NoSenseEtAl 我关心的是更多的可维护性和错误预防。使用
std::shared_ptr,您需要确保使用 PImpl 的类确保正确完成复制和分配,并且不会发生意外引入两个对象共享同一个 impl 对象的可能性。对于std::unique_ptr,这是由类型给出的,如果你做错了什么,你会得到一个编译器错误。它肯定不会阻止你所有的错误,但可以防止你形成常见的错误。
标签: c++ shared-ptr c++20 pimpl-idiom