重载赋值操作符与提供隐式构造函数

时间:2022-10-14 21:41:50

I have just learned on page 563 of C++ Primer (5th edition) that one can overload the assignment operator. So, if I am writing a class C and it makes sense to assign an integer to an object of this class, then I can provide an assignment operator with an rhs of type int. Then the clients of my class can write:

我刚刚在c++ Primer(第五版)第563页了解到,赋值操作符可以过载。因此,如果我正在编写一个类C,并且将一个整数分配给这个类的对象是有意义的,那么我可以提供一个赋值操作符,它的类型是int。

C c;
...
c = 5;

Question: Is it true that if such an assignment makes sense, then an implicit constructor C(int); should also make sense? If so, then I should really define this constructor instead (which has other uses as well) and never need to overload the assignment operator. Am I missing something?

问:如果这样的赋值有意义,那么隐式构造函数C(int)是真的吗?还应该有意义吗?如果是,那么我应该真正定义这个构造函数(它也有其他用途),并且永远不需要重载赋值操作符。我遗漏了什么东西?

3 个解决方案

#1


4  

If C defines a non-explicit constructor taking an int then you don't necessarily need an assignment operator taking an int, but it may end up being more efficient.

如果C定义了一个带int的非显式构造函数,那么就不需要赋值运算符带int,但它最终可能会更有效。

If operator=(int) exists:

如果操作符=(int)存在:

C c; //default constructor
c = 5; //assignment from int

If C(int) exists and operator=(int) does not:

如果C(int)存在且运算符=(int)不存在:

C c; //default constructor
c = 5; //construction of temporary from int, then assignment from C

If move semantics are efficient for C then the latter may be acceptable. If not, you might want to define that operator=(int) anyway. Ultimately, this depends on a number of factors, like how often you are going to be assigning to C, how expensive copies are etc. Understand the issues, work out how they apply to your class, then choose the most reasonable solution.

如果移动语义对于C是有效的,那么后者是可以接受的。如果不是,您可能需要定义运算符=(int)。最终,这取决于许多因素,比如分配给C的频率,拷贝的成本等等。理解问题,找出它们如何应用于类,然后选择最合理的解决方案。

#2


1  

Is it true that if such an assignment makes sense, then an implicit constructor C(int); should also make sense?

如果这样的赋值有意义,那么隐式构造函数C(int)是真的吗?还应该有意义吗?

In depends. The difference between the assignment and implicit constructor is that in assignment there is already a set-up object, while in implicit conversion you have to create an object given int only.

在决定。赋值和隐式构造函数之间的区别是,在赋值中已经有一个设置对象,而在隐式转换中,只能创建一个给定整数的对象。

In a most common scenario, the assignment operator will just forget all the data of the original object. In such a case you should be also able to convert int to C. However, I can imagine situations when the assignment operator actually uses some data from the original object. In such a case, no conversion constructor can be thought of.

在最常见的场景中,赋值操作符只会忘记原始对象的所有数据。在这种情况下,您还应该能够将int转换为c。然而,我可以想象当赋值操作符实际使用来自原始对象的一些数据时的情况。在这种情况下,不能考虑任何转换构造函数。

A simple example: consider numerical simulation project, which has class Mesh — set of points in space on which the calculations are done, and class Field that is set of values on that points (say, temperatures in that points). A Field can not exist without a Mesh:

一个简单的例子:考虑数值模拟项目,该项目具有类网格——在空间中完成计算的点集,以及类字段,该字段是该点上的值集(例如,该点的温度)。一个没有网格的领域是不存在的:

class Field {
    const Mesh& mesh;
    std::vector<int> data;
};

Here you can not create Field(int) constructor, as you do not have a mesh. However, you may think of Field::operator=(int) assignment, which will replace all data values with a given int, keeping mesh intact.

这里不能创建Field(int)构造函数,因为没有网格。但是,您可以考虑字段::operator=(int)赋值,它将用给定的int替换所有数据值,保持网格的完整性。

So, the answer to the first your question is: no, even is assignment makes sense, the conversion does not always make sense.

所以,第一个问题的答案是:不,即使赋值是有意义的,转换并不总是有意义的。

However, if that's not your case and both conversion and assignment makes sense, than refer to @TartanLlama's answer.

但是,如果不是你的情况,转换和赋值都有意义,请参考@TartanLlama的答案。

#3


0  

You don't need the assignment operator too, just the constructor from an int

您不需要赋值操作符,只需要来自int的构造函数

  1. C c(5); Calls the constructor taking an int as an argument.
  2. C C(5);调用将int作为参数的构造函数。
  3. C c = 5; Calls the constructor taking an int as an argument.
  4. C C = 5;调用将int作为参数的构造函数。
  5. C c; c = 5; Calls the default constructor, the second statement will call the constructor to an int, then the assignment operator.
  6. C C;c = 5;调用默认构造函数,第二个语句将调用构造函数到int,然后是赋值操作符。

(2) can cause confusion. The constructor must be used since the object does not exist.

(2)可能会导致混乱。由于对象不存在,所以必须使用构造函数。

#1


4  

If C defines a non-explicit constructor taking an int then you don't necessarily need an assignment operator taking an int, but it may end up being more efficient.

如果C定义了一个带int的非显式构造函数,那么就不需要赋值运算符带int,但它最终可能会更有效。

If operator=(int) exists:

如果操作符=(int)存在:

C c; //default constructor
c = 5; //assignment from int

If C(int) exists and operator=(int) does not:

如果C(int)存在且运算符=(int)不存在:

C c; //default constructor
c = 5; //construction of temporary from int, then assignment from C

If move semantics are efficient for C then the latter may be acceptable. If not, you might want to define that operator=(int) anyway. Ultimately, this depends on a number of factors, like how often you are going to be assigning to C, how expensive copies are etc. Understand the issues, work out how they apply to your class, then choose the most reasonable solution.

如果移动语义对于C是有效的,那么后者是可以接受的。如果不是,您可能需要定义运算符=(int)。最终,这取决于许多因素,比如分配给C的频率,拷贝的成本等等。理解问题,找出它们如何应用于类,然后选择最合理的解决方案。

#2


1  

Is it true that if such an assignment makes sense, then an implicit constructor C(int); should also make sense?

如果这样的赋值有意义,那么隐式构造函数C(int)是真的吗?还应该有意义吗?

In depends. The difference between the assignment and implicit constructor is that in assignment there is already a set-up object, while in implicit conversion you have to create an object given int only.

在决定。赋值和隐式构造函数之间的区别是,在赋值中已经有一个设置对象,而在隐式转换中,只能创建一个给定整数的对象。

In a most common scenario, the assignment operator will just forget all the data of the original object. In such a case you should be also able to convert int to C. However, I can imagine situations when the assignment operator actually uses some data from the original object. In such a case, no conversion constructor can be thought of.

在最常见的场景中,赋值操作符只会忘记原始对象的所有数据。在这种情况下,您还应该能够将int转换为c。然而,我可以想象当赋值操作符实际使用来自原始对象的一些数据时的情况。在这种情况下,不能考虑任何转换构造函数。

A simple example: consider numerical simulation project, which has class Mesh — set of points in space on which the calculations are done, and class Field that is set of values on that points (say, temperatures in that points). A Field can not exist without a Mesh:

一个简单的例子:考虑数值模拟项目,该项目具有类网格——在空间中完成计算的点集,以及类字段,该字段是该点上的值集(例如,该点的温度)。一个没有网格的领域是不存在的:

class Field {
    const Mesh& mesh;
    std::vector<int> data;
};

Here you can not create Field(int) constructor, as you do not have a mesh. However, you may think of Field::operator=(int) assignment, which will replace all data values with a given int, keeping mesh intact.

这里不能创建Field(int)构造函数,因为没有网格。但是,您可以考虑字段::operator=(int)赋值,它将用给定的int替换所有数据值,保持网格的完整性。

So, the answer to the first your question is: no, even is assignment makes sense, the conversion does not always make sense.

所以,第一个问题的答案是:不,即使赋值是有意义的,转换并不总是有意义的。

However, if that's not your case and both conversion and assignment makes sense, than refer to @TartanLlama's answer.

但是,如果不是你的情况,转换和赋值都有意义,请参考@TartanLlama的答案。

#3


0  

You don't need the assignment operator too, just the constructor from an int

您不需要赋值操作符,只需要来自int的构造函数

  1. C c(5); Calls the constructor taking an int as an argument.
  2. C C(5);调用将int作为参数的构造函数。
  3. C c = 5; Calls the constructor taking an int as an argument.
  4. C C = 5;调用将int作为参数的构造函数。
  5. C c; c = 5; Calls the default constructor, the second statement will call the constructor to an int, then the assignment operator.
  6. C C;c = 5;调用默认构造函数,第二个语句将调用构造函数到int,然后是赋值操作符。

(2) can cause confusion. The constructor must be used since the object does not exist.

(2)可能会导致混乱。由于对象不存在,所以必须使用构造函数。