構造函數


構造析構

一、構造函數

1、介紹

構造函數,它是一種特殊的函數,主要用來在創建對象時初始化對象,即為對象的成員變量賦初始值。

2、構造函數的定義:

//1 構造函數名和類名相同
//2 構造函數沒有返回值類型,和返回值
//3 構造函數可以重載,需要滿足函數重載的條件
class student
{
public:
	student(){}			//無參構造(默認構造)
	student(int a){}	//有參構造(帶參構造)
};

3、構造函數的調用時機

//1 在創建一個新的對象的時候會調用
//調用無參構造
student stu;
student *p = new student;
//調用帶參構造
student stu(1);
student *p = new student(1);

4、構造函數的特點

/*
*	1 如果一個類中沒有顯示的給出構造函數,系統會自動給出一個缺省的(隱式)什么都不干的構造函數
*	2 如果類中有多個構造函數,那么通常會有不同的參數列表和函數體
*	3 如果用戶提供了無參(帶參)構造,那么系統就不再提供默認構造
*	4 類中如果只有帶參構造,沒有無參構造,那么就不能調用默認構造的方式初始化對象,想用這種方式初始化對象就要提供無參構造
*
*
*/

5、拷貝構造(一種特殊的構造)

//1 拷貝構造是一種特殊的構造函數,用自身這種類型來構造自身
//例;
student stu1;
student stu2 = sut1;//在這一句就會調用拷貝構造
拷貝構造的定義:

​ 1 沒有寫拷貝構造,系統會提供一個隱式的拷貝構造,而這個拷貝構造的操作,我們可以理解為,是用 ‘ = ’ 號一個一個的將存在於對象中的數據成員賦值給新創建的對象中。

//	2 自定義拷貝構造
//		類名(const 類名& 引用名){}
//	這里的const不加也可以,但是這里是拷貝,也就是復制的意思,所以加上,防止被改
//	在函數體里面通常的做法是逐一拷貝傳進來的對象的成員,賦值給新的對象,當然也可以自己定義內容

//例:
class Student
{
	int id;
public:
	Student(const Student&stu)
	{
	this->id=stu.id;
	//把傳進來對象的id賦值給當前調用對象的id
	}
}

拷貝構造的調用:
//1 在用同種類的對象,去初始化另一個對象的時候(注意是在定義對象初始化,不是賦值)
Student stu1;
Student stu2=stu1;//顯示調用拷貝構造
Student stu3(stu2);//隱式調用拷貝構造
Student *pStu=new Student(stu3);

//2 在函數傳參時,函數的形參是類對象
void fun(Student stu){}
fun(stu1);//在函數調用傳參時調用拷貝構造

//3 如果一個函數的返回值類型是對象,在函數調用結束,返回對象的時候調用拷貝構造
Student fun1(Student stu)
{
    return stu;
}
//這里在函數調用的時候會調用兩次拷貝構造,函數傳參一次,函數返回時一次

//函數返回時再次調用拷貝構造的原因:stu形參是屬於棧區的,不能return出來,出了函數就直接被釋放了,所以想要返回出來,就要再拷貝一次。
6、深拷貝與淺拷貝

1、淺拷貝

​ 淺拷貝構造我們不寫,系統也會提供一個默認的拷貝構造,而這個拷貝構造的操作,我們可以理解為,是用 ‘ = ’ 號一個一個的賦值的,我們將之稱為,淺拷貝。在用指針的時候我們就知道兩個同等類型的指針之間用 ‘ = ’ 號賦值,是兩個指針的地址指向同一個內存,那么就可能會存在一個問 題,就是兩個對象的指針都指向同一個內存,那么如果其中一個對象把該內存釋放了,就會導致另外一個對象的指針變成野指針。

2、深拷貝

​ 也就是在有上述問題的時候才需要深拷貝,而深拷貝做的事情也就是自己定義拷貝構造,給新的對象的指針申請內存,來存內容,而不是兩個對象的指針指向同一個內存

//示例:
class Student
{
	char *name;
public:
	Student(char *name)
	{
	this->name=new char[strlen(name)+1];//加1是為了保存'\0'
	strcpy(this->name,name);
	}
	Student(const Student& stu)
	{
		//這個自定義拷貝構造函數做的事,其實就是給新對象的指針申請		內存來存數據,如果有其他成員,那么也要記得賦值
	this->name=new char[strlen(stu.name)+1];//加1是為了存'\0'
	strcpy(this->name,s
           tu.name);
	}
}

什么時候要自己寫拷貝構造?

​ 類中有動態申請內存的時候,必須要寫。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM