C++类的构造与析构的一点细节问题

关于构造函数,复制构造,和析构的问题。

类的复制构造函数有两种调用的类型,一种是显示的调用 例如  class A = B, 另外一种是隐式的调用,例如传递形参,或者函数返回时。

今天发现自己对以类类型作为形参使用时的构造和析构认识不够,所以又找了找资料,写了个验证程序来熟悉了一下。

         有三种情况下需要调用复制构造函数:

        1) 一个对象以值传递的方式传入函数体;

        2) 一个对象以值传递的方式从函数返回;

        3) 一个对象需要通过另外一个对象进行初始化;

        按理说,一个调用过程中,类需要先构造,这里的构造包括普通构造和复制构造两类,然后生命周期结束后需要进行析构。

        如下程序:

#include <iostream>

class Test {
public:	 
	Test() 
	{
	       std::cout<< "调用无参数类型的构造函数!!\n" << std::endl ; 
		   data = 0 ; 
	}

	Test( int num )
	{
		  data = num ; 
		  std::cout << "调用有参数的构造函数!!\t 参数为:\t" <<  num << std::endl ; 
	}

	~Test()
	{
		   std::cout << "调用类的析构函数!!!\n" << std::endl; 
	}

	Test(const Test &  a )
	{
	       this->data = a.data ; 
		   std::cout << "调用复制构造函数!!\n" <<std::endl; 
	}

private:
	int  data; 
};

// 测试按值传递的函数
Test passValue( Test  b  )
{
	  return b ; 
}

//测试按引用传递的函数
Test passReference(Test & b)
{
      return b ; 
}

    以上写了一个简单的类,包括两个函数,一个passValue用于测试按值传递过程中,类的构造和析构过程,另外一个passReference用于测试传递引用时,类的构造和析构过程 。

第一个测试main函数如下:

int main()
{
	  Test t1 = passValue(1) ;
	  Test t2 = passValue(t1) ; 
	  return 0 ; 
}

函数输出结果:

调用有参数的构造函数!!         参数为:        1  
调用复制构造函数!!

调用类的析构函数!!!

调用复制构造函数!!

调用复制构造函数!!

调用类的析构函数!!!

调用类的析构函数!!!

调用类的析构函数!!

 

一共调用了一次带参数的构造函数,三次复制构造函数,和四次析构函数
调用的过程如下:
Test t1 = passValue(1)  语句中包括一次带形参的构造,一次复制构造,一次析构
1,首先隐式的调用带参数的构造函数Test(1) 成为一个临时Test类,记为temp1,(单个参数的构造函数这里有一个隐式的转换调用过程)
2,调用复制构造函数,将temp1复制给t1。
3,析构temp1,调用第一次析构函数来析构temp1,这点是我之前忽略的。
 Test t2 = passValue(t1) 语句中包括两次复制构造函数,和一次析构函数
 4,  调用复制构造函数对passValue()函数中的形参"t1"进行复制构造
 5,  调用复制构造函数对t2进行复制构造。
 6,  调用析构函数,析构形参“t1”
 7,  调用析构函数,析构t2, // 因为t1和t2是在栈上分配的,所以析构过程先析构t2,然后析构t1
 8,  调用析构函数,析构t1,


------------------------------------------------------------------------------------------------------------------

使用第二个测试函数进行测试

int main()
{
		Test t1; 
		Test t2 = passReference(t1) ; 
		return 0 ; 
}


输出如下:

调用无参数类型的构造函数!!

调用复制构造函数!!

调用类的析构函数!!!

调用类的析构函数!!!

 

此次调用调用了一次无参数的构造函数,一次复制构造,然后两次析构

Test  t1; 中调用了一次无参的构造函数

Test t2 = passReference(t1) ; 中调用了一次复制构造函数,

其中因为passReference(t1) 传递的的为引用,所以不生成形参临时变量,少了一次构造和一次析构。

最后调用两次析构函数,分别析构 t2 和 t1  ;

另外 引用本身不是数据类型,只是某个目标变量的别名,所以使用passReference(1)是肯定不行的。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值