C++ 临时对象和对象的生存周期

临时对象生成的三种条件 :
①形参为对象,实参为数值常量,传参就会生成临时对象
②隐式类型转换
③函数返回一个对象
先定义一个 Test 对象

class Test
{
public:
	Test()
	{
		ma = mb = 0;
		std::cout<<"Test()"<< std::endl;
	}
	Test(int a)
	{
		ma = a;
		mb = 0;
		std::cout<<"Test(int)"<< std::endl;
	}
	Test(int a, int b)
	{
		ma = a;
		mb = b;
		std::cout<<"Test(int,int)"<< std::endl;
	}
	//以上是三个不同的构造函数
	
	Test(const Test& rhs)   //因为没有指针所以不需要深拷贝 
	{
		ma = rsh.ma;
		mb = rsh.mb;
		std::cout<<"Test(const Test&)"<< std::endl;
	}
	~Test()
	{
		std::cout << "~Test()"  << std::endl;
	}
	Test& operator=(const Test& rhs)
	{
		if(this != &rhs)
		{
			ma = rhs.ma;
			mb = rhs.mb;
		}
		std::cout<<"operator="<< std::endl;
		return *this;
	}
	

private:
int ma;
int mb;
};
 Test func1(const Test& ts)
 {
	 Test tmp(ts);
  	std::cout << "void func1(const Test&)" << std::endl;
  	return tmp;
  }
  Test func2(Test ts)
  {
  	std::cout << "void func2(const Test&)" << std::endl;
  	return ts;
  }
int main()
{
	Test a = 10;
	a = 20;
	const Test& b = 20;
	Test test1(10,20);
	Test rt = func1(test1);
	Test c = func2(30);
	return 0;
}

用几个例子说明一下临时对象的生存周期
Test a = 10;
这个语句时可以运行成功的,那么是如何做到将一个整形值赋值给一个对象的呢?首先,调用一个整形参数的构造函数 ,生成一个临时对象,而这个临时对象的生成是为了生成一个新对象,所以就以生成临时对象的方式生成 a 这个对象,这样就可以少生成一次对象,从而达到优化的效果。因此这个对象的生存周期从这句开始一直到该函数运行结束。

a = 20;
这个语句的运行和上面那句有一点不同,首先还是调用一个整形参数的构造函数,生成一个临时对象,而这个临时对像的生成不是为了生成新对象,所以这个临时对象的生存周期到这个语句执行结束。

const Test& b = 20;
执行这条语句时, 首先还是调用一个整形参数的构造函数,生成一个临时对象,临时对象是为了生成新对象,所以被优化,直接生成 b 这个临时对象。而 b 这个对象加了引用(引用能提升临时对象的生存周期,提升为和引用变量相同的生存周期),所以对象 b 的生存周期一直到该程序结束

Test* ptest1 = &Test(10,20) ;
分析这条语句,赋值符号右边调用两个int型参数的构造函数生成一个临时对象,对其取地址,并赋值给Test型的指针。看上去貌似没有问题,但是由于生成的是临时对象,并且没有引用提升生存周期,所以该指针指向一个临时对象,在执行完这条语句后,用该指针访问这段内存,值不会改变,但是以后系统可能会把该段内存分配给其他变量或者函数,那时候用ptest1访问就会造成无法估计的后果

Test rt = func1(Test ts);
主函数调用func1函数,那么实参传形参的时候,生成临时对象的生存周期一直到该函数调用结束,而返回的对象由临时量带回,返回值返回的也是一个临时对象,在调用方的栈帧上,临时对象的生成是为了生成一个新对象,所以被优化了。因此这个对象的生存周期到主函数结束。

Test c = func2(30);
这条语句执行的时候,首先调用func2函数,然后实参传形参,先调用一个整形参数的构造函数,生成一个临时对象,接着调用拷贝构造函数,将临时对象中的值赋给 ts,执行func2中的return语句时,由于返回的是一个对象,返回值有临时量带回调用方函数,main中,c 接收函数的返回值,c 并不是个已存在的对象,因此调用拷贝构造函数生成c。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值