C++复制构造函数和赋值运算符

3
我是一名有用的助手,可以为您翻译文本。
我已经听过很多次,如果提供了复制构造函数,就必须提供赋值运算符。然而,有时候一个类可以使用复制构造函数但不需要赋值运算符。
例如:
class A {
public:
  const int myVar;

  A(const int var) : myVar(var) {};
  A(const A& other) : myVar(other.myVar) {};
};

那么这样做是一个可怕的事情吗?赋值运算符需要被定义但是私有化吗?这样的类仍然可以进行复制构造吗?


这个类甚至不需要显式复制构造函数,因为编译器生成的构造函数正是你所需要的。 - R. Martinho Fernandes
1
@R.MartinhoFernandes:我假设这是一个简单的代码示例,用于表达问题。 - Alok Save
1个回答

4

这样做是不是很糟糕的事情?
不,不是。
并非所有类都需要同时具备可复制构造和可赋值性。具有可复制构造但不可赋值的类是完全有效的。

这样的类仍然可以进行复制构造吗?
可以。
只要您的类提供了一个public复制构造函数,那么您的类就可以进行复制构造。

赋值运算符是否需要被定义但设置为私有的?
这取决于您的使用情况。
如果您的类需要可赋值性,则最好不要有const成员。

由于默认的编译器生成的复制赋值运算符会尝试分配给一个不允许的常量成员,因此如果您的代码需要复制赋值运算符,则必须提供自己的重载版本。但是,无论如何,这个重载版本都不能提供期望的赋值语义。

如果您的类对象不需要可赋值性,则不要定义它。如果您的代码意外使用它,编译器将生成一个错误。


它不需要是可分配的,但必须是可复制构造的。但是我习惯于总是被告知,如果它有一个复制构造函数,那么它也必须具有赋值运算符,但在这里这是没有意义的。 - tpg2114
@tpg2114:你所提到的是C++03中的三五法则或者C++11中的五法则。但它只是大多数情况下适用的指导方针,而不是标准强制执行的条件(尽管如果标准这样做会有所帮助)。类可以是可复制构造的但不可赋值的,在这种情况下打破指导方针也是可以的。 - Alok Save
2
三/五法则允许声明一些必需的项目为私有,并将它们保持未实现状态。但是它们应该被声明。你声明它们是因为你不希望编译器为你生成意外的东西,而不是因为你计划实际使用它们。 - n. m.
在这种情况下,OP不需要提供任何重载声明。如果OP的代码以某种奇怪而晦涩的方式使用赋值操作符,则将调用隐式复制赋值运算符,并且它将发出编译器错误(由于const成员)。它将实现通过不仅提供重载运算符的定义,而只提供声明所能实现的效果。在这种情况下的优势是错误将在编译时检测到,而不是在链接阶段检测到。 - Alok Save

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接