类对象的生存周期

本文详细解析了C++中对象拷贝构造、赋值运算符重载及临时对象的创建与管理过程。通过具体代码示例,阐述了不同情况下对象拷贝的触发机制,包括拷贝构造函数、赋值运算符重载的作用,以及如何处理自赋值与资源释放。同时,探讨了临时对象的生命周期与引用临时对象的方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <iostream>

using namespace std;

class CGoods
{
public:
	CGoods()
	{
		std::cout << this << " :CGoods::CGoods()" << std::endl;
		mname = new char[1];
		mname = '\0';
		mamount = 0;
		mprice = 0.0;
	}
	CGoods(char* name, int amount, float price)
	{
		std::cout << this << " :CGoods::CGoods(char*,int,float)" << std::endl;
		mname = new char[strlen(name) + 1];
		strcpy(mname, name);
		mamount = amount;
		mprice = price;
	}
	//CGoods good3 = good2;
	//对象自己的成员,可以任意访问自己的其他任何访问限定成员方法和成员变量
	//CGoods(CGoods* const this, const CGoods &rhs)
	CGoods(const CGoods &rhs)
	{
		cout << &rhs << "->" << this <<endl;
		cout << "CGoods(const CGoods&)"<<endl;
		
		mname = new char[strlen(rhs.mname)+1];
		strcpy(mname, rhs.mname);
		mamount = rhs.mamount;
		mprice = rhs.mprice;
	}
		
	//explicit;禁止隐式对象的生成
	//explicit CGoods(float price)
	CGoods(float price)
	{
		std::cout << this << " :CGoods::CGoods(float)" << std::endl;
		mname = new char[1];
		mprice = price;
	}
	
	//可以不加引用,用值传递,但是效率不高,因为会产生新的对象
	//不加引用时初始化的时候调用拷贝构造函数,产生新的CGoods对象
	//成员方法的意义
	//1、防止rhs被修改
	//2、隐式产生的临时量都是常量,加const为了引用隐式生成的临时量
	CGoods& operator=(const CGoods &rhs)
	{
		cout << &rhs << "->" << this <<endl;
		cout << "operator=(const CGoods&)"<<endl;

		//防止自赋值
		if(this != &rhs)
		{
			//释放当前对象占用的其他资源
			delete[] mname;

			mname = new char[strlen(rhs.mname)+1];
			strcpy(mname, rhs.mname);
			mamount = rhs.mamount;
			mprice = rhs.mprice;
		}
		return *this;
	}
	~CGoods()
	{
		std::cout << this << " :CGoods::~CGoods()" << std::endl;
		delete[] mname;
		mname = NULL;
	}
	void show()
	{
		cout << "name:"<<mname<<endl;
		cout << "amount:"<<mamount<<endl;
		cout << "price:"<<mprice<<endl;
	}
private:
	char* mname;
	int mamount;
	float mprice;
};
void test(CGoods *p)
{
	cout<<"call test"<<endl;
	p->show();
}
int main()
{   
	test(&CGoods("aaa",10,2.2));
	CGoods good1;
	CGoods good2("aaa",10,2.2);  
	CGoods good3 = good2;
	good1 = good3;
	
	cout<<"----------------------------------"<<endl;
	CGoods good4 = CGoods("bbb",15,6.6);
	
	cout<<"----------------------------------"<<endl;
	good1 = CGoods("bbb",15,6.6);

	cout<<"----------------------------------"<<endl;
	good1 = (CGoods)("bbb",15,6.6);
	good1 = (CGoods)12.5;//good1 = CGoods(12.5);
	
	cout<<"----------------------------------"<<endl;
	good1 = 89.5;

	cout<<"----------------------------------"<<endl;
	CGoods *p = &CGoods("bbb",15,6.6);
	CGoods &q = CGoods("bbb",15,6.6);
	
	cout<<"----------------------------------"<<endl;
	int array[3][4] = {(12,4,5,67),(4,32,12,8),(5,6,7,90)};
	cout<<"array[0][1]: "<< array[0][1]<<endl;//8
	cout<<"array[1][2]: "<< array[1][2]<<endl;//0
	cout<<"array[2][3]: "<< array[2][3]<<endl;//0

	cout<<"----------------------------------"<<endl;
	CGoods good5;
	cout<<"----------------------------------"<<endl;

	return 0;
} 

test(&CGoods(“aaa”, 10, 2.2));
      先构造,再打印call test,再show,最后析构
在这里插入图片描述
CGoods good1;//调用默认构造函数
在这里插入图片描述
CGoods good2(“aaa”,10,2.2); //调用带有三个参数的函数
在这里插入图片描述
CGoods good3 = good2;//调用拷贝构造函数
在这里插入图片描述
good1 = good3;//调用赋值运算符的重载
在这里插入图片描述
CGoods good4 = CGoods(“bbb”,15,6.6);
      CGoods(“bbb”,15,6.6) 显示生成临时对象
      临时对象的生存周期 -》 临时对象所在的语句
      用临时对象构造同类型的新对象时,此时,临时对象不生成,用构造临时对象的方法构造目标对象
      CGoods good4(“bbb”,15,6.6);
在这里插入图片描述

good1 = CGoods(“bbb”, 15, 6.6);
      显示生成临时对象 先调用带有三个参数构造函数,构造一个一个临时对象再用临时对象通过赋值运算符的重载给good1赋值,
在这里插入图片描述

good1 = (CGoods)(“bbb”, 15, 6.6);
      类型强转,对象是逗号表达式,把最后一个参数留下,剩下的都没有作用
      显示生成临时对象
good1 = (CGoods)12.5;
good1 = CGoods(12.5);
      两者一样,都是显示生成临时对象
      上述三者都一样,都是good1 = (CGoods)12.5;
      先调用带有 float 参数的构造函数构造一个临时对象,临时对象调用运算符的重载函数给 good1 赋值,函数结束,释放临时对象
在这里插入图片描述

      类类型 <-> 其他类型
      其他类型 -> 类类型//看该类有没有构造函数,以他类型作为参数,隐式生成一个临时对象
      内置类型 产生的临时量都是常量(临时量都被放在寄存器中),不能被修改
      自定义类型 产生的临时量都是变量,可以被修改
      89.5 --> CGoods(float)
      隐式产生的临时量都是常量

good1 = 89.5;
      类型转换 CGoods <- double//隐式生成临时对象
在这里插入图片描述
CGoods *p = &CGoods(“bbb”,15,6.6);
在这里插入图片描述
CGoods &q = CGoods(“bbb”,15,6.6);
//用引用引用临时变量,临时对象提升成引用变量的生存周期
在这里插入图片描述
int array[3][4] = {(12,4,5,67),(4,32,12,8),(5,6,7,90)};
cout<<"array[0][1]: "<< array[0][1]<<endl;//8
cout<<"array[1][2]: "<< array[1][2]<<endl;//0
cout<<"array[2][3]: "<< array[2][3]<<endl;//0
//因为是 (),而不是 {},(12,4,5,67) 是逗号表达式
//相当于 int arr[3][4] = {67, 8, 90};
在这里插入图片描述
CGoods good5;
在这里插入图片描述
函数结束,释放 good1、good2、good3、good4、good5、&p
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值