【发布时间】:2019-01-06 15:06:48
【问题描述】:
这可以看作是对例如Why shared pointer assignment does 'swap'?.
问题是关于 e.g. in boost 使用的 Copy&Swap 习语。
我明白 Copy&Swap 的好处是可以重用现有代码,从而避免重复和错误。但是有两种情况(实际上可以减少到另一种)不是最优的:
- 智能指针实例相同
- 包含的指针是一样的
对于shared_ptr,引用计数器自动递增,对于intrusive_ptr(仅限boost),它们可能是。所以复制一份成本很高。
这可以避免,如果分配是这样实现的:
smart_ptr& operator=(const smart_ptr& other){
if(this->ptr_ == other.ptr_) return *this;
smart_ptr(other).swap(*this); // I assume I can simply do this here, right?
return *this;
}
smart_ptr& operator=(smart_ptr&& other){
smart_ptr(std::move(other)).swap(*this);
return *this;
}
这难道不是最快、最安全的实施方式吗?还是有什么我没有发现的问题?
如果是最快的,为什么不使用 boost 或 stdlib?
澄清第 2 点。考虑以下代码:
smart_ptr a(new foo);
auto b = a;
...
// Eventually:
a = b;
这不是自分配&a != &b。 Copy&Swap确实涉及对引用计数器的不必要修改。
【问题讨论】:
-
copy ctor 没有被调用,它已经被优化了,因为它们只是交换、移动和复制指针。
-
自赋值是一种非常少见的情况。通过复制和交换,您可以摆脱自分配测试,并为常见情况获得一点额外的性能,而且是在其良好的代码重用之上。
-
这与指针复制 ctor 和 smart_ptr 复制 ctor 被调用无关。 @phön 我添加了一个片段以澄清它不是(仅)自我分配,在这种情况下性能会丢失
-
分支比无用的小型复制操作成本更高。这是 CPU 优化的结果。所以最好不要进行检查。也许有人会提供一个关于这个的链接(我没有时间寻找它)?
-
@Flamefire 好吧,我认为即使是这种情况也很罕见。我不确定这是否是除了代码重用与幼稚实现之外的复制和交换的唯一参数
标签: c++ smart-pointers copy-and-swap