为什么在调用重载赋值运算符时调用复制构造函数?
why copy constructor is called at the time of calling overloaded assignment operator?
我正在尝试了解构造函数和赋值运算符的使用。我正在尝试使用下面的程序。
#include <iostream>
using namespace std;
class myclass {
int x;
public:
myclass (int p) {
cout << "calling constructor" << endl;
x = p;
}
myclass () {
cout << "calling constructor with no arguments" << endl;
x = 0;
}
myclass (myclass &t) {
cout << "calling copy constructor" << endl;
x = t.x;
}
myclass operator=(myclass &t) {
cout << "calling assignment operator" << endl;
x = t.x;
return *this;
}
void show () {
cout << "val = " << x << endl;
}
};
int main() {
myclass a1;
a1.show();
myclass a2 = a1;
a2.show();
myclass a3(a2);
a3.show();
myclass a4(200);
a2 = a4;
a2.show();
return 0;
}
输出:
calling constructor with no arguments // call 1
val = 0
calling copy constructor // call 2
val = 0
calling copy constructor // call 3
val = 0
calling constructor // call 4
calling assignment operator // call 5
calling copy constructor // call 6 i am not able to understand this print line
val = 200
调用 1,是从 myclass a1 完成的;
调用 2,是从 myclass a2 = a1 完成的;
调用 3,是从 myclass a3(a2) 完成的;
调用 4,是从 myclass a4(200) 完成的;
调用 5,从 a2 = a4 完成;
但我无法得知调用 6 的来源,它是根据指令调用的:
a2 = a4;
但是,它如何调用复制构造函数?
任何 help/pointer 都会有很大的帮助。我正在从 c 进入 cpp,因此请多多包涵。
(你的复制构造函数和赋值运算符有点格式错误:它们应该将 const
引用作为参数,而赋值运算符应该 return 一个 引用 不是一个值)。
对于 myclass a2 = a1;
,a2
尚不存在。因此调用复制构造函数以使用 a1
.
创建 a2
但是对于a2 = a4
,a2
已经存在,所以赋值运算符用于赋值 a2
到a4
.
所以规则本质上是:如果对象不存在,则需要构造它。您观察到的输出可以通过应用此规则来解释。
改为
myclass& operator=(myclass &t)
然后:
calling constructor with no arguments
val = 0
calling copy constructor
val = 0
calling copy constructor
val = 0
calling constructor
calling assignment operator
val = 200
如果您 return 按值,将调用复制构造函数。
Return 通过引用避免调用复制构造函数。
myclass operator=(myclass &t) {
cout << "calling assignment operator" << endl;
x = t.x;
return *this;
}
上面的函数returns按值。
按值返回是调用复制构造函数的情况之一。
另外 AFAIK,这并不总是正确的(return 通过值调用复制构造函数),因为一些编译器实现了 return 值优化。
您的赋值运算符 returns 由 value,因此当它 returns.
时会生成另一个副本
这就是第六个电话的来源。
通常,赋值运算符 return 是 引用 ,因此当您 return *this
时,您实际上是 return *this
:
myclass& operator=(myclass &t) {
// ^
我正在尝试了解构造函数和赋值运算符的使用。我正在尝试使用下面的程序。
#include <iostream>
using namespace std;
class myclass {
int x;
public:
myclass (int p) {
cout << "calling constructor" << endl;
x = p;
}
myclass () {
cout << "calling constructor with no arguments" << endl;
x = 0;
}
myclass (myclass &t) {
cout << "calling copy constructor" << endl;
x = t.x;
}
myclass operator=(myclass &t) {
cout << "calling assignment operator" << endl;
x = t.x;
return *this;
}
void show () {
cout << "val = " << x << endl;
}
};
int main() {
myclass a1;
a1.show();
myclass a2 = a1;
a2.show();
myclass a3(a2);
a3.show();
myclass a4(200);
a2 = a4;
a2.show();
return 0;
}
输出:
calling constructor with no arguments // call 1
val = 0
calling copy constructor // call 2
val = 0
calling copy constructor // call 3
val = 0
calling constructor // call 4
calling assignment operator // call 5
calling copy constructor // call 6 i am not able to understand this print line
val = 200
调用 1,是从 myclass a1 完成的;
调用 2,是从 myclass a2 = a1 完成的;
调用 3,是从 myclass a3(a2) 完成的;
调用 4,是从 myclass a4(200) 完成的;
调用 5,从 a2 = a4 完成;
但我无法得知调用 6 的来源,它是根据指令调用的:
a2 = a4;
但是,它如何调用复制构造函数?
任何 help/pointer 都会有很大的帮助。我正在从 c 进入 cpp,因此请多多包涵。
(你的复制构造函数和赋值运算符有点格式错误:它们应该将 const
引用作为参数,而赋值运算符应该 return 一个 引用 不是一个值)。
对于 myclass a2 = a1;
,a2
尚不存在。因此调用复制构造函数以使用 a1
.
a2
但是对于a2 = a4
,a2
已经存在,所以赋值运算符用于赋值 a2
到a4
.
所以规则本质上是:如果对象不存在,则需要构造它。您观察到的输出可以通过应用此规则来解释。
改为
myclass& operator=(myclass &t)
然后:
calling constructor with no arguments
val = 0
calling copy constructor
val = 0
calling copy constructor
val = 0
calling constructor
calling assignment operator
val = 200
如果您 return 按值,将调用复制构造函数。 Return 通过引用避免调用复制构造函数。
myclass operator=(myclass &t) {
cout << "calling assignment operator" << endl;
x = t.x;
return *this;
}
上面的函数returns按值。 按值返回是调用复制构造函数的情况之一。 另外 AFAIK,这并不总是正确的(return 通过值调用复制构造函数),因为一些编译器实现了 return 值优化。
您的赋值运算符 returns 由 value,因此当它 returns.
时会生成另一个副本这就是第六个电话的来源。
通常,赋值运算符 return 是 引用 ,因此当您 return *this
时,您实际上是 return *this
:
myclass& operator=(myclass &t) {
// ^