C++01——类和对象_类的生存周期

C++01——类和对象_类的生存周期

        已经报班学习了一年的C,C++,Linux,大二一年学会了很多东西,但刚升大三,看看身边的同学都在努力奋斗着,回想自己的学习成果,感觉真的很浅。所以决定把C++和Linux的知识,通过看录屏,重新学习一下,通过CSDN来记录知识点,也希望大家可以多交流指教。朋友圈学长,学姐进入阿里的,进入腾讯的,都挺羡慕的。感觉这些足以让我有动力更努力了。大三的我,开始吧。

     类和对象:6个默认函数之四

生成对象(构造函数):步骤一,开辟对象的内存空间;步骤二,调用构造函数

销毁对象(析构函数):步骤一,调用析构函数;步骤二,释放对象所占空间

1.构造函数:初始化对象所占内存空间

2.析构函数:释放对象所占资源

3.拷贝构造函数:用一个已存在的对象来构造一个相同类型的新对象

形参必须使用引用对象:否则形参对象会死循环。

4.赋值运算符的重载函数

用一个已存在的对象给另一个相同类型已存在的对象赋值

形参要使用常引用

常引用的作用:1.防止实参被修改

扫描二维码关注公众号,回复: 11655578 查看本文章

                         2.接收隐式生成的临时对象

对象的生存周期

注:代码中的#if 0与#endif位置自己移动,每个/*  */与代码组成一个例子。

//对象的生存周期
#include <stdlib.h>
#include <iostream>
#include <stdio.h>
using namespace std;

class Object
{
public:
	Object(int num)
	{
		cout <<  "Object::Object(int)" << endl;
		mname = new char[1]; 
		mnum = num;
	}
	Object(char* name)//构造函数
	{
	   cout <<  "Object::Object()" << endl;
	   mname = new char[strlen(name) + 1];
	   strcpy(mname,name);
	   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;
	}

	~Object()//析构函数
	{
		cout <<  "Object::~Object()" << endl;
		delete[] mname;
		mname = NULL;
	}
private:
	char* mname;
	int mnum;

};
 void Func1( Object obj)
 {
	 Object tmp (obj);
 }
 void Func2( Object& obj)
 {
	 Object tmp (obj);
 }
 
 
int main()
{
     /*
       形参是对象类型  建议大家使用引用
       效率高:少了空间开辟,少了两个函数调用
    
	//Func1(无引用):实参传形参时,形参生成开辟内存,生成对象二obj
    //Func2(有引用):不会有形参对象生成

	总结:当调用Func1时,调用三个构造函数;
	      当调用Func2时,调用两个构造函数。(无形参对象生成)
    */
	 Object ob1("object");//生成对象一ob1
	 Func1(ob1);//实参传形参时,形参生成开辟内存,生成对象二obj,生成对象三tmp
#if 0	
	 Func2(ob1);


	 /*
	 new,在堆上开辟内存,需要手动释放,在delete调用时,调用析构函数进行释放
	 
	 调用函数顺序:第一句调用构造函数;
	               第二句调用构造函数;
				   第一句调用析构函数。(第二句delete调用点时调用析构)
	 */
	 Object obj1("object1");
     Object* pobj = new Object("object heap");//栈上的指针指向堆上的对象
	 
	 
	 /*
	 =右边是临时对象的生成,临时对象应该在“;”结束之前调用析构函数
	 
	第二行的调用析构函数改变原因:引用会提升临时对象的生存周期,
	       提升到从调用点到main函数结束,与引用对象的生存周期相同。

    调用函数顺序:第一句调用构造函数;
	              第二句调用构造函数;
				  第一句调用析构函数。(第二句main函数结束之前,调用析构函数)
	 */
	 Object* pobj = &Object("object");	
	 Object& pobj1 = Object("object");


	 /*
	    等号右边显示调用一个临时对象
	    临时对象在这句中的作用:为了生成新对象
		当临时对象是为了生成新对象时,以生成临时对象的方式生成新的对象,编译器优化掉临时对象的生成
	 总结:只调用一个构造函数,一个析构函数。(等号左边的临时对象的生被优化掉)
	 */
	 Object obj = Object("object");//只生成一个对象
	 
	 
	 /*
	   等同于: Object obj ("object");
	   总结:调用一个构造函数,一个析构函数
	 */
	 Object obj ="object";


	 /*
	      等号右边为逗号表达式,选择最后一个数据,则构造10的类型函数,所以选择调用整形的构造函数。
		  并且生成临时对象时优化,生成一个对象
     总结:调用一个构造函数,一个析构函数
	 */
	 Object obj = (Object)("object",10);

#endif
 }

生命周期的例题:

//对象的生存周期的例题
#include <stdlib.h>
#include <iostream>
#include <stdio.h>
using namespace std;

class Test
{
public:
	Test(double c = double())
	{
		cout << "c:" << c <<endl;
		ma = mb = 0;
		mc = c;
		cout << "Test(double):" << mc << endl;
	}
	Test(int a,float b,double c)
	{
		ma = a;
		mb = b;
		mc = c;
		cout << "Test(int,float,double):"<< mc << endl;
	}
	Test (const Test& rhs)
	{
		ma = rhs.ma;
		mb = rhs.mb;
		mc = rhs.mc;
		cout << "Test(Test):"<< mc << endl;
	}
	Test& operator=(const Test& rhs)
	{
		if (this != &rhs)
		{
			ma = rhs.ma;
			mb = rhs.mb;
			mc = rhs.mc;
		}
		cout << "opertaor=(Test):"<< mc << endl;
		return* this;
	}

	~Test()
	{
		cout << "~Test()" << mc << endl;
	}
private:
	int ma;
	float mb;
	double mc;
};
Test gtest1(10,20.1f,1.1);
static Test gtest2(10,20.1f,1.2);

int main()
{
	Test ltest1(10,20.2f,2.1);
	Test ltest2(2.2);
	Test ltest3 = ltest1;
	ltest2 = ltest3;

	static Test ltest4(10,20.3f,2.4);

	Test ltest5 = Test(20,20.1f,2.5);
	ltest5 = Test(30,30.1f,2.5);

	Test ltest6 = Test(20,20.1f,2.6);
	ltest6 = (Test)(30,30.1f,2.6);

	Test* ptest7 = new Test(20,20.4f,2.7);
	
	Test* ptest8 = &Test(20,20.4f,2.8);
	Test& ptest9 = Test(20,20.4f,2.9);

	delete ptest7;

	return 0;
}
Test gtest3(10,20.1f,1.3);
static Test gtest4(10,20.1f,1.4);

代码运行结果与解析如下:

对于对象生命周期的习题,建议网上多找找,做做题,弄清楚,有问题留言指教呦~

猜你喜欢

转载自blog.csdn.net/qq_41103495/article/details/100896876
今日推荐