我试图理解构造函数和赋值运算符的使用。我正在尝试使用以下程序。
#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;
但是,它如何调用复制构造函数?
任何帮助/指针都将是一个很好的帮助。我从c潜入cpp,所以请耐心等待。
答案 0 :(得分:2)
(复制构造函数和赋值运算符稍有不正确:它们应该使用const
引用作为参数,赋值运算符应该返回引用而不是值)。
使用myclass a2 = a1;
,a2
尚不存在。因此,使用a2
调用复制构造函数来创建a1
。
但是a2 = a4
a2
已经存在,因此赋值运算符用于将 a2
分配给a4
。
所以规则本质上是:如果一个对象不存在则需要构造它。您可以通过应用此规则来解释您观察到的输出。
答案 1 :(得分:2)
myclass operator=(myclass &t) {
cout << "calling assignment operator" << endl;
x = t.x;
return *this;
}
上述函数按值返回。 按值返回是调用复制构造函数的情况之一。 同样是AFAIK,这并不总是正确的(通过值调用复制构造函数返回),因为一些编译器实现了返回值优化。
答案 2 :(得分:1)
将其更改为
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
如果按值返回,将调用复制ctor。 通过引用返回以避免调用copy ctor。
答案 3 :(得分:1)
您的赋值运算符按值返回,因此返回时会生成另一个副本。
第六次来电的来源。
通常情况下,赋值运算符会返回引用,因此当您return *this
时,确实会返回*this
:
myclass& operator=(myclass &t) {
// ^