2013-05-01 88 views
4

一位同事和我正在辩论const或参考成员是否永远是正确的事情。除非您编写自己的副本并移动忽略引用或常量成员的运算符,否则const和引用成员将使类不可复制且不可移动。我无法找到一种情况,即忽略复制或移动某些成员只是因为它们是引用或const是有意义的。参考成员的良好做法?是否是const成员?

我认为拥有一个不可移动的物体在逻辑上是非常罕见的,而且这个选择只与该类是否为location invariant有关。一个不可复制的对象比较常见,但是选择让一个类不可复制与它是否拥有逻辑上不可复制的资源,是否拥有唯一所有权等有关。我无法想到一个唯一的原因具有参考或const成员或不意味着该类应该要么这些性状(不可复制或不可移动)

他们应该曾经使用的?应该一个而不是另一个?什么是例子?

+1

我不认为他们让班级不可复制或不可移动;它不能被复制/移动到*中,但它肯定可以被复制/移动*。它更像是“不可分配”而不是“不可复制”。 – Angew 2013-05-01 13:16:37

+1

我发现参考成员对于像函数对象这样的东西非常有用。 – 2013-05-01 13:27:17

+0

关于不可移动物体的好奇声明。我会说,通常没有理由将对象移动。实体对象当然不应该是可移动的,因为它们不会像临时对象那样出现。而使价值语义可移动的对象是一种优化,不一定适用于许多类型,并且意味着可移植性的重大损失(至少在今天),并且增加了复杂性。事实上,我认为移动应该只在探查者说你需要时才能使用。 – 2013-05-01 13:35:46

回答

5

我想不出有任何理由具有基准或const成员与否的唯一特性将意味着类应该有这两种特质(不可复制或不可移动)

我想前提是错误的。

有一个const数据成员或引用数据成员不会使类不可复制的:它只是使得它不可能分配它或它的破坏性的方式举动。

这是因为对于const对象或引用而言,破坏性移动操作并不健全:由于const对象的状态永远不会被更改,并且引用不能被解除绑定,所以它将违背它们的语义。

然而,事实证明X不是复制分配或移动转让的不妥协构建这些对象的副本,这是可能性 - 正如你所指出 - 稳健经营。下面的程序,例如,将精编:

struct X 
{ 
    X() : x(0), rx(x) { } 

    const int x; 
    const int& rx; 
}; 

int main() 
{ 
    X x; 
    X x1 = x; // Copy-initialization (copy-constructs x1 from x) 
    X x2 = X(); // Copy-initialization (copy-constructs x2 from a temporary) 
} 

编译器将隐式生成拷贝构造函数为你和举措将退化为副本。如果这种移入副本的恶化不适合您班级的语义,那么您可能会认为没有const或引用成员。