问题起于构造函数调用次数问题,问如下程序调用几次构造函数,答案为6次。
#include<iostream>
using namespace std;
class Myclass {
public:
Myclass(int i):number(i){
count++;
cout << "有参构造函数 第" << count<<"次调用构造函数"<<endl;
}
Myclass(Myclass&m) {
number = m.number;
count++;
cout << "拷贝构造函数 第" << count << "次调用构造函数"<<endl;
}
~Myclass(){}
private:
static int count;
int number;
};
int Myclass::count = 0;
Myclass fun(Myclass m) {
Myclass tem = m;
return tem;
}
void main() {
Myclass obj1(10), obj2(20);
Myclass obj3(obj1);
obj2 = fun(obj3);
}
运行结果如下
第1、2、3次调用都很好理解,第4次调用源自传递实参,第5次调用源自创建临时变量tem;问题是第6次是在哪。
构造函数只在创建变量初始化时使用,那么第6 次的调用肯定不是因为
obj2 = fun(obj3);
中的赋值符号“=”;
可以增加一行进行测试(放在obj2 = fun(obj3);下一行)
运行结果为
obj2 = obj3;
新增赋值行没有构造函数的调用,只是简单的赋值。
那么原因只可能在fun函数中,fun只有两行代码,因此可以推断原因出自return语句,此时想到函数返回时会创建一个临时变量,对
obj2=fun(obj3);
这段可以理解为
1 Myclass outer_tem=fun(obj3);
2 obj2=outer_tem;
当然第一行实际并不存在,他是隐式创建的。
因为fun函数结束后函数中的变量tem也已经被释放,但还需要将tem的值赋给obj2,因此需要一个临时空间来存储并赋值给obj2,赋值完后就消失,因此第6次构造函数调用源自函数返回时临时变量的创建。
我们可以通过重载运算符=来验证
当重载=不反回任何值时
#include<iostream>
using namespace std;
class Myclass {
public:
Myclass(int i):number(i){
count++;
cout << "有参构造函数 第" << count<<"次调用构造函数"<<endl;
}
Myclass(Myclass&m) {
number = m.number;
count++;
cout << "拷贝构造函数 第" << count << "次调用构造函数"<<endl;
}
void operator=(Myclass m) {
this.number=m.number;
cout << "赋值,非拷贝构造" << endl;
}
~Myclass() { cout << count--<<"析构函数调用" << endl; }
private:
static int count;
int number;
};
int Myclass::count = 0;
Myclass fun(Myclass m) {
Myclass tem = m;
return tem;
}
void main() {
Myclass obj1(10), obj2(20);
Myclass obj3(obj1);
//obj2 = fun(obj3);
obj2 = obj3;
}
运行结果为
可以看到赋值完后就没有构造函数的调用了
将重载赋值“=”的代码段改为,此时有返回值
Myclass operator=(Myclass m) {
this->number = m.number;
cout << "赋值,非拷贝构造" << endl;
return m;
}
运行结果如下
可以看到赋值后还有一次构造函数的调用,此次的构造函数即为返回时临时变量创建所引起的。