构造函数、复制构造函数、赋值运算符的调用

构造函数、复制构造函数、赋值运算符的调用

结合下面的例子来讨论三者的调用顺序

#include <iostream>
#include <vector>
using namespace std;
class Foo {
public:
	Foo() {
		cout << "Foo constructor" << endl;
	}
	Foo(const Foo&) {
		cout << "Foo copy constructor" << endl;
	}
	Foo& operator= (const Foo&) {
		cout << "Foo operator =" << endl;
		return *this;
	}
	~Foo() {
		cout << "Foo destructor" << endl;
	}
};
int f(Foo) {
	return 0;
}
int g(const Foo&) {
	return 0;
}
Foo h() {
	Foo foo;
	return foo;
}
int main(void) {
	Foo vf1; //1
	f(vf1);//2
	g(vf1);//3
	Foo vf2 = vf1;//4
	vf2 = h();//5
	Foo *pf = new Foo();//6
	delete pf;//7
	vector<Foo> vecf(3);//8
	return 0;
}
  • 1:调用无参构造函数,故:Foo constructor。
  • 2:向函数f传入刚才构造的对象vf1,函数结束值vf1要销毁。故:Foo copy constructor,Foo destructor
  • 3:由于g函数的形参是引用,故不会调用构造函数
  • 4:由于定义对象,并对此对象用产生的对象进行复制(建立一个新的对象,并用另外一个对象进行初始化),故:Foo copy constructor
  • 5:若编译器不做优化,执行结果:h函数先创建对象,即Foo constructor;返回此对象时,故会创建临时对象,并对此对象进行复制,即Foo copy constructor;执行完以后,h函数结束作用域,foo对象销毁,即Foo destructor;由于只是赋值,并没有定义新的对象,调用赋值运算符,即Foo operator =;最后临时变量的使命完成,进行销户;即Foo destructor。而编译器做优化以后,返回值优化的目的就是为了省去临时对象的创建和销毁的巨大开销,这种开销对程序员不可见,但是会潜在对程序性能产生很大影响。执行结果:Foo constructor,Foo operator =,Foo destructor 。返回值优化具体详细细节见https://blog.csdn.net/hycxag/article/details/82999739
  • 6:堆上new一个Foo对象,即:Foo constructor
  • 7:delete删除对应new分配的对象,即:Foo destructor
  • 8:当我们声明一个具有初始长度的类容器的时候,编译器会自动调用该类的构造函数对容器进行初始化,所以一般会认为产生3个Foo constructor的输出。实际上,这里的过程是首先生成一个临时对象,然后以该临时对象为蓝本进行copy,即调用3次复制构造函数将临时对象复制到容器中的每个元素,这时临时对象已经完成其使命,因而编译器调用析构函数将其释放,即:Foo constructor,Foo copy constructor,Foo copy constructor,Foo copy constructor,Foo destructor
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章