c++类对象初始化方式总结

在《inside the c++ object model》一书中谈到copy constructor的构造操作,有三种情况下,会以一个object的内容作为另一个object的初值:

第一种情况: XX aa = a;
第二种情况: XX aa(a);
第三种情况: extern fun(XX aa); fun(a)函数调用
第四种情况: XX fun(){...}; XX a = fun();函数返回值的时候

下面我们就上述的四种情况来一一验证:

class ClassTest{
public:
	ClassTest()//定义默认构造函数
	{
		c[0] = '\0';
		cout << "ClassTest()" << endl;
	}
	ClassTest& operator=(const ClassTest &ct) //重载赋值操作符
	{
		strcpy_s(c, ct.c);
		cout << "ClassTest& operator=(const ClassTest &ct)" << endl;
		return *this;
	}
	ClassTest(const char *pc)
	{
		strcpy_s(c, pc);
		cout << "ClassTest (const char *pc)" << endl;
	}  
	ClassTest(const ClassTest& ct)//复制构造函数
	{
		strcpy_s(c, ct.c);
		cout << "ClassTest(const ClassTest& ct)" << endl;
	}
private:
	char c[256];
};

ClassTest func(ClassTest temp){
	return temp;
}

int main(){
	cout << "ct1: ";
	ClassTest ct1("ab");//直接初始化  
	cout << "ct2: ";
	ClassTest ct2 = "ab";//复制初始化  
	/*输出说明:
	ClassTest ct2 = "ab";
	它本来是要这样来构造对象的:首先调用构造函数ClassTest(const char *pc)函数创建一个临时对象,
	然后调用复制构造函数,把这个临时对象作为参数,构造对象ct2。然而编译也发现,复制构造函数是
	公有的,即你明确地告诉了编译器,你允许对象之间的复制,而且此时它发现可以通过直接调用重载的
	构造函数ClassTest(const char *pc)来直接初始化对象,而达到相同的效果,所以就把这条语句优化为
	ClassTest ct2("ab")。
	*/
	cout << "ct3: ";
	ClassTest ct3 = ct1;//复制初始化  
	cout << "ct4: ";
	ClassTest ct4(ct1);//直接初始化  
	cout << "ct5: ";
	ClassTest ct5 = ClassTest();//复制初始化 
	cout << "ct6: ";
	ClassTest ct6;//复制初始化
	ct6 = "caoyan is a good boy!";
	cout << "ct7: ";
	ClassTest ct7;
	ct7 = func(ct6);
	return 0;
}
测试结果:

我们可以看到,比较复杂的是ct6和ct7,其中ct6还是比较好理解的,ct7这种情况比较难懂,为什么会有两个拷贝构造函数的调用????

第一次拷贝构造函数的调用:第一次很简单,是因为函数参数的传递,将ct6作为参数传递给temp,用ct6的值初始化temp会调用拷贝构造函数;

第二次拷贝构造函数的调用:因为要返回一个ClassTest对象,我们的编译器怎么做????首先它将temp对象拷贝到func函数的上一级栈帧中,它的上一级栈帧是main函数的栈帧,那么当函数返回时,参数出栈,temp对象的内存空间就会被收回,但是它的值已经被拷贝到main栈帧的一个预留空间中,所以从temp到预留空间的拷贝也是调用拷贝构造函数,最后一步就是给ct7赋值,毫无疑问调用赋值构造函数;对栈帧不同的同学可以看看《程序员的自我修养》一书,里面讲得很详细!!!!


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值