在移动构造函数中抛弃constness是否可以接受?

时间:2014-10-24 09:27:05

标签: c++ c++11 const move-semantics

假设我有一个 Foo 类,它有一个指向 Bar 的私有指针:

class Foo
{
private:
  Bar * bar;

public:
  Foo () : bar (new Bar ())
  {}

  ~Foo ()
  {
    delete bar;
  }
};

如果永远不应该将指针bar重新分配给不同的实例,那么将指针本身const用于阻止我(或维护者)将来这样做是有意义的:

private:
  Bar * const bar;

我喜欢在机会出现的地方这样做。

如果我想写一个移动构造函数,它看起来像这样:

Foo (Foo && f) :
   bar (f.bar)
{
  f.bar = NULL;  // uh oh; f.bar is const.
}

我可以通过抛弃f.bar的常量或者首先不使const成为“使错误消失”。这些都不是我想要做的事情。我宁愿不完全删除const因为它是有原因的。另一方面,扔掉constness ring为我敲响了警钟,这是我从未经常做过的事情。我的问题是:在这样的移动构造函数中抛弃const是否被认为是可以接受的做法?有没有更好的方法我没有考虑过?

我不认为我的问题与此问题相同:Use const_cast to implement the move constructor

3 个答案:

答案 0 :(得分:6)

如果在某些情况下你必须更改指针(即使它只是一个案例),那么它可能不应该是const

然而,即使把这个想法放在一边,使用const_cast从对象中删除constness,然后使用cast的结果调用undefined行为。 const_cast一个最初不是const的变量是唯一安全的。

答案 1 :(得分:4)

你基本上是自相矛盾的 你说的是#34;我不想在任何情况下改变它#34;并且你在说#34;我想在移动一个物体时改变它"。

因此,如果存在需要更改的情况,那么它不是const,您可以放心地删除它。

如果您确定需要它const,则可以添加另一个确定所有权的布尔值(如果需要处理资源生命周期)。因此,只有在调用拥有该对象的析构函数时才可以释放指向的对象。

答案 2 :(得分:3)

如果可能,请改为使用unique_ptr

std::unique_ptr<Bar> bar;
Foo(Foo&& f) : bar(std::move(f.bar)){}
// or maybe you won't even have to declare move constructor

通过这种方式,您不仅可以获得更高的安全性和舒适度,而且您也不会意外地使用=重写它,您必须致电.reset(),这样您才能再三考虑这样做(我想这是你的目标)。