gcc shared_ptr复制赋值实现

时间:2015-12-14 21:49:33

标签: c++ c++11 gcc shared-ptr libstdc++

我正在GCC 5中扫描// set default color var hex = 0x00ff00; var u,v,xx,yy,ii; // initialise arrow bases var lines = new THREE.Geometry(); // loop through Geometry[i].vertices.forEach(function(point,j) { // rescale xx = Math.floor((point.x-data[i].x0)/data[i].dx); yy = Math.floor((point.y-data[i].y0)/data[i].dy); ii = data[i].nx*yy+xx; u = data[i].frame[data[i].xvec][ii]*data[i].scale; v = data[i].frame[data[i].yvec][ii]*data[i].scale; lines.vertices.push( new THREE.Vector3(point.x+data[i].dx/2, point.y+data[i].dy/2,1), new THREE.Vector3(point.x+data[i].dx/2+u, point.y+data[i].dy/2+v,1) ); }); var mat = new THREE.LineBasicMaterial({color:hex}) line[i] = new THREE.LineSegments( lines, material); scene.add(line[i]); 实施,我看到以下内容:

shared_ptr

我的问题是为什么在交换之前临时的附加移动构造?我假设编译将删除任何额外的开销 - 但为什么不调用 __shared_ptr& operator=(__shared_ptr&& __r) noexcept { __shared_ptr(std::move(__r)).swap(*this); return *this; } ?我有什么聪明的副作用吗?

我看到类中的其他函数也使用相同的模式实现,我可以理解接受const引用但是rvalue引用的情况吗?

3 个答案:

答案 0 :(得分:7)

首先,这就是标准所说的内容,海湾合作委员会只是遵循了这一点。

这样,赋值运算符的后置条件为__r.empty(),这是你的建议无法实现的,因此按照你的建议实现它会对标准所说的产生不同的影响,因此不符合要求。

即。这个断言成立:

auto p1 = std::make_shared<int>(1);
auto p2 = std::make_shared<int>(2);
p1 = std::move(p2);
assert( !p2 );

&#34;聪明的副作用&#34;是你创建一个新的 shared_ptr,它在交换后最终保持旧值*this,然后超出范围。这意味着*this的旧值不会在__r中结束。

答案 1 :(得分:1)

因为我们需要在引用的rvalue上调用析构函数来减少实例数。

答案 2 :(得分:1)

通过将__r的内容移动到作为函数return销毁的临时内容中,确保移出的对象__r所指的是剩下的在空旷的状态。我猜他们想把这个逻辑放在一个地方,移动构造函数,看起来像这样。

__shared_ptr(__shared_ptr&& __r) noexcept
  : _M_ptr(__r._M_ptr), _M_refcount()
{
  _M_refcount._M_swap(__r._M_refcount);
  __r._M_ptr = 0;
}

就个人而言,我更喜欢以下实施,据我所知,这是相同的。

widget&
operator=(widget&& other) noexcept
{
  widget temp {};
  swap(*this, temp);
  swap(*this, other);
  return *this;
}

可以使用像这样实现的移动构造函数来补充它。

widget(widget&& other) noexcept : widget {}
{
  swap(*this, other);
}

我假设有一个

void
swap(widget&, widget&) noexcept;

ADL可以找到的重载以及widget的默认构造函数为noexcept