c++类的生存周期

博客聚焦于C++类的生命周期相关内容,虽未给出具体内容,但可知围绕C++类展开,涉及信息技术领域中后端开发的C++编程知识。

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


#include<iostream>
using namespace std;
/*
       类和对象 
	   1、构造函数
	             初始化对象所占内存空间
	   2、析构函数
	             释放对象所占资源
	   3、拷贝构造函数
	              用一个已存在的对象来构造一个相同类型的对象
				   形参必须使用引用对象
	 4、赋值运算符的重载函数
	              用一个已存在的对象给另一个相同类型的已存在的对象赋值
				  形参要使用常引用
				  常引用的作用:1、防止实参被修改2、接收隐式生成的临时对象
*/
//对象的生存周期


class  Object
{

public:

	//Object(char*name)

	Object(int num)
	{
		cout<<"Object::Object(int)"<<endl;
		mname=new char[1];
		mnum=num;
	}
	Object(char*name="",int num=0)
	{
		cout<<"Object::Object(char,int)"<<endl;
		mname=new char[strlen(name)+1];
		strcpy(mname,name);
		Show();
		if(num==0)
		{
			mnum=strlen(mname+1);
		}
		
	}
	Object(const  Object& rhs)
	{
		cout<<"Object::Object(Object)"<<endl;
		mname=new char[strlen(rhs.mname)+1];
		strcpy(mname,rhs.mname);
		mnum=rhs.mnum;
	}
	Object & operator=(const Object&rhs)
	{
		cout<<"Object::operator=(Object)"<<endl;
		if(this!=&rhs)
		{
			delete[] mname;
			mname=new char[strlen(rhs.mname)+1];
			strcpy(mname,rhs.mname);
			mnum=rhs.mnum;

		}
		return *this;
	}
	void Show()
	{
		cout<<"name:"<<mname<<endl;
	}
	~Object()
	{
		cout<<"Object::~Object()"<<endl;
		delete[] mname;//堆上的资源
		mname=NULL;
	}

private:
	char* mname;
	int mnum;
};
//对象的生存周期
Object gobj1("global  object1");//1调用char*类型的构造函数,最后一个销毁,main函数结束之后,程序结束之前
static Object gobj2("global  object2");//2

//先全局后局部
int main()
{
	cout<<"-------------"<<endl;
	Object lobj1("local object1");//1
	cout<<"-------------"<<endl;
	Object lobj2(10);//2

	static Object sobj("static object");//3


	Object lobj3=lobj1;//拷贝构造函数
	lobj3=lobj2;//赋值运算符的重载函数

	Object* pobj4=new Object("local object4");//堆上返回的都是一个地址,栈上的指针指向堆上的一个对象,堆上的空间需要手动释放
	cout<<"-------------"<<endl;

	Object aobj5[2];//声称对象数组  掉默认构造函数
	cout<<"-------------"<<endl;

	Object* pobj6=&Object("local object6");//右边显示生成临时对象  把对象的地址给了栈上的指针  ,有临时对象生成,临时对象遇到;销毁,poj6指向无效地址,地址虽然归还给系统,如果内存块里面的值没有被修改,结果就是正确的,打印错误的话,内存块已经被分配,数据被覆盖
	Object& robj7=(Object)("local object7",20);//引用回提升 临时对象的生存周期,和引用对象相同一直到main结束才销毁

	Object& pobj8=*(new Object("local object8"));//=右边,堆上对象生成,返回地址
     
	Object obj9="object9";//构造一个新的对象 Object obj9("object9")
	delete pobj4;//堆上的对象销毁,有析构函数的调用

	cout<<"-------------"<<endl;
	Object obj10=Object("object10");//=右边显示生成临时对象   ,生成临时对象的目的就是为了构造一个新的对象,就一生成临时对象的方式生成新对象,整个代码只有一个对象生成
	obj9=Object("object11");//右边的对象给左边赋值,赋值运算符的重载函数,;到了临时对象就要销毁,不是生成一个新的对象,不会被优化,有一个析构函数的调用
	cout<<"-------------"<<endl;

	return 0;
}
Object gobj3("global  object3");//3
static Object gobj4("global  object4");//4











/*int main()
{
	//Object obj="object";//等同于Object obj("object")调用构造函数
	Object obj=(Object)("object",10);//逗号表达式,用参数10,显示生成临时对象,是为了生成新对象,以
	//以生成临时对象的方式生成新对象。有优化。 整个过程只有一个对象生成。调用有整形参数的构造函数
	return 0;
}
*/








//构造函数是第一种
//int main()
//{
//	//临时对象的作用是为了生成新对象   以生成临时对象的方式生成新的对象
//	Object obj=Object("object");//有一个对象生成      这个临时对象的作用是为了生成新的对象,编译器优化掉
//	return 0;
//}








//引用会提升临时对象的生存周期  从调用点到mian()结束
//int main()
//{
//	Object *pobj=&Object("object");//显示生成临时对象  取他的地址      有两个函数执行 有对象的生成 也有对象的销毁   临时对象的生存周期
//	cout<<"______________"<<endl;
//	Object &pobj1=Object("object");//右边显示生成临时对象   左边用引用引用这个临时对象  只有一个函数调用      &会提升临时对象的生存周期 
//	cout<<"______________"<<endl;
//
//	return 0;
//}













//int main()
//{
//	Object obj1("object1");
//	Object*  pobj=new Object("object   heap");//对象在堆上开辟
//	delete pobj;//不仅要把堆内存释放掉  还要调用析构函数
//	cout<<"*_____________*"<<endl;
//
//	return 0;
//}















/*


	形参是对象类型 建议使用引用
	void Func(Object obj)
{
	Object temp(obj);
}

	
	int main()
{
	Object ob1("object1");
	Func(ob1);
	return 0;

}*/







 

<think>嗯,用户想了解C++成员变量的生命周期。好,我得先回忆一下这方面的知识,然后组织成清晰的中文解释。首先,成员变量的生命周期应该和它们所属对象的生存期有关,对吧?那对象的生存期又由它们的存储期决定,比如自动存储期、静态存储期或者动态存储期。 用户可能想知道成员变量何时被创建和销毁,特别是当对象被构造和析构的时候。需要分情况讨论:普通成员变量、静态成员变量、引用成员变量,可能还有const成员变量或者通过继承来的成员。对了,构造函数初始化的顺序和析构函数的逆序也很重要,特别是基和成员对象的初始化顺序。 另外,静态成员变量的生命周期和的生命周期相关,而不是单个对象,所以它们的初始化和销毁时间点可能不同。还有,如果成员变量是指针或者动态分配的内存,虽然指针本身的生命周期和对象一样,但指向的内存需要手动管理,这部分可能需要提醒用户注意内存泄漏。 用户可能在使用智能指针,比如unique_ptr或shared_ptr,这些会影响成员变量的生命周期管理,但问题可能更基础,先讲清楚基本概念再提智能指针作为扩展比较好。 需要确保回答结构清晰,分点说明不同情况,比如普通成员、静态成员、引用和常量成员,以及构造和析构的顺序。还要注意使用正确的中文术语,比如“生存期”、“存储期”、“构造函数”、“析构函数”等。 可能用户在实际编程中遇到了成员变量未初始化或提前销毁的问题,所以强调初始化和销毁的顺序,以及不同存储型的影响。另外,动态分配内存的情况需要特别说明,避免内存管理错误。 总之,回答应该分步骤,先总述成员变量生命周期与对象的关系,再分情况详细说明,最后可能加上注意事项或常见问题,比如初始化顺序、静态成员的特殊性等。确保用例子说明,比如普通成员变量在对象创建时分配,析构时释放;静态成员在程序开始时初始化,结束时销毁等。</think>C++成员变量的生命周期与对象本身的生存期紧密相关。以下是关键点分步说明: 1. **普通成员变量(非静态)** - **创建时机**:当对象被实例化时(调用构造函数时),成员变量依次初始化。 - **销毁时机**:当对象生命周期结束时(调用析构函数时),成员变量按声明逆序销毁。 - 示例: ```cpp class MyClass { public: int a; // 生命周期跟随对象 double b; // 同上 }; ``` 2. **静态成员变量(static)** - **创建时机**:在程序启动时初始化(位于全局数据区),与对象实例化无关。 - **销毁时机**:程序结束时销毁,遵循静态存储期规则。 - 需要特别注意: ```cpp class MyClass { public: static int count; // 需在外单独定义:int MyClass::count = 0; }; ``` 3. **引用成员变量(&)** - 必须通过构造函数初始化列表初始化 - 生命周期与所引用的外部变量绑定 ```cpp class RefHolder { public: int& ref; RefHolder(int& external) : ref(external) {} // 必须初始化 }; ``` 4. **构造/析构顺序规则** - **初始化顺序**:按中声明顺序初始化(与初始化列表顺序无关) - **析构顺序**:与初始化顺序相反 - 继承场景:基成员先初始化,派生成员后初始化 5. **特殊成员的生命周期管理** - **动态内存成员**:若成员是指针且指向堆内存,需在析构函数中手动释放 ```cpp class ResourceHolder { int* ptr; public: ResourceHolder() : ptr(new int[100]) {} ~ResourceHolder() { delete[] ptr; } // 必须显式释放 }; ``` - **智能指针成员**:推荐使用`std::unique_ptr`/`std::shared_ptr`实现自动管理 ```cpp #include <memory> class SmartHolder { std::unique_ptr<int[]> smartPtr; public: SmartHolder() : smartPtr(new int[100]) {} // 无需手动释放 }; ``` **关键总结**: - 普通成员变量生命周期 ≈ 对象生命周期 - 静态成员变量生命周期 ≈ 程序运行周期 - 引用成员的生命周期依赖外部绑定对象 - 包含动态资源时需要特别注意手动管理(或使用智能指针)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值