基礎 C 的拷貝構造和析構函式以及深淺拷貝

2021-10-06 01:41:14 字數 4726 閱讀 3996

4.2.2 建構函式的分類及呼叫

4.2.3 拷貝構造函式呼叫時機

4.2.4 構造函式呼叫規則

4.2.5 深拷貝與淺拷貝

4.2.6 初始化列表

4.2.8 靜態成員

物件的初始化和清理也是兩個非常重要的安全問題

​ 乙個物件或者變數沒有初始狀態,對其使用後果是未知

​ 同樣的使用完乙個物件或變數,沒有及時清理,也會造成一定的安全問題

c++利用了建構函式和析構函式解決上述問題,這兩個函式將會被編譯器自動呼叫,完成物件初始化和清理工作。

物件的初始化和清理工作是編譯器強制要我們做的事情,因此如果我們不提供構造和析構,編譯器會提供

編譯器提供的建構函式和析構函式是空實現。

建構函式:

主要作用在於建立物件時為物件的成員屬性賦值,建構函式由編譯器自動呼叫,無須手動呼叫。

析構函式:

主要作用在於物件銷毀前系統自動呼叫,執行一些清理工作。

建構函式語法:類名(){}

建構函式,沒有返回值也不寫void

函式名稱與類名相同

建構函式可以有引數,因此可以發生過載

程式在呼叫物件時候會自動呼叫構造,無須手動呼叫,而且只會呼叫一次

析構函式語法: ~類名(){}

析構函式,沒有返回值也不寫void

函式名稱與類名相同,在名稱前加上符號 ~

析構函式不可以有引數,因此不可以發生過載

程式在物件銷毀前會自動呼叫析構,無須手動呼叫,而且只會呼叫一次

class

person

//析構函式

~person()

};void

test01()

intmain()

兩種分類方式:

​ 按引數分為: 有參構造和無參構造

​ 按型別分為: 普通構造和拷貝構造

三種呼叫方式:

​ 括號法

​ 顯示法

​ 隱式轉換法

示例:

//1、建構函式分類

// 按照引數分類分為 有參和無參構造 無參又稱為預設建構函式

// 按照型別分類分為 普通構造和拷貝構造

class

person

//有參建構函式

person

(int a)

//拷貝建構函式

person

(const person& p)

//析構函式

~person()

public

:int age;};

//2、建構函式的呼叫

//呼叫無參建構函式

void

test01()

//呼叫有參的建構函式

void

test02()

intmain()

c++中拷貝構造函式呼叫時機通常有三種情況

使用乙個已經建立完畢的物件來初始化乙個新物件

值傳遞的方式給函式引數傳值

以值方式返回區域性物件

示例:

class

person

person

(int age)

person

(const person& p)

//析構函式在釋放記憶體之前呼叫

~person()

public

:int mage;};

//1. 使用乙個已經建立完畢的物件來初始化乙個新物件

void

test01()

//2. 值傳遞的方式給函式引數傳值

//相當於person p1 = p;

void

dowork

(person p1)

void

test02()

//3. 以值方式返回區域性物件

person dowork2()

void

test03()

intmain()

預設情況下,c++編譯器至少給乙個類新增3個函式

1.預設建構函式(無參,函式體為空)

2.預設析構函式(無參,函式體為空)

3.預設拷貝建構函式,對屬性進行值拷貝

構造函式呼叫規則如下:

如果使用者定義有參建構函式,c++不在提供預設無參構造,但是會提供預設拷貝構造

如果使用者定義拷貝建構函式,c++不會再提供其他建構函式

示例:

class

person

//有參建構函式

person

(int a)

//拷貝建構函式

person

(const person& p)

//析構函式

~person()

public

:int age;};

void

test01()

void

test02()

intmain()

深淺拷貝是面試經典問題,也是常見的乙個坑

淺拷貝:簡單的賦值拷貝操作

深拷貝:在堆區重新申請空間,進行拷貝操作(因為原來物件有堆空間,那麼深拷貝則需要再去開闢對應的堆空間,去承接同樣的堆空間資料,否則將會導致兩個資料指向同乙個堆空間,導致風險)

示例:

class

person

//有參建構函式

person

(int age ,

int height)

//拷貝建構函式

person

(const person& p)

//析構函式

~person()

}public

:int m_age;

int* m_height;};

void

test01()

intmain()

作用:

c++提供了初始化列表語法,用來初始化屬性

語法:建構函式():屬性1(值1),屬性2(值2)… {}

示例:

class

person

//初始化列表方式初始化

person

(int a,

int b,

int c)

:m_a

(a),

m_b(b)

,m_c

(c)void

printperson()

private

:int m_a;

int m_b;

int m_c;};

intmain()

4.2.7 類物件作為類成員

c++類中的成員可以是另乙個類的物件,我們稱該成員為 物件成員

例如:

class

aclass

b

b類中有物件a作為成員,a為物件成員

那麼當建立b物件時,a與b的構造和析構的順序是誰先誰後?

class

phone

~phone()

string m_phonename;};

class

person

~person()

void

playgame()

string m_name;

phone m_phone;};

void

test01()

intmain()

當類中成員是其他類物件時,我們稱該成員為 物件成員

構造的順序是 :先呼叫物件成員的構造,再呼叫本類構造

析構順序與構造相反

靜態成員就是在成員變數和成員函式前加上關鍵字static,稱為靜態成員

靜態成員分為:

靜態成員變數

所有物件共享同乙份資料

在編譯階段分配記憶體

類內宣告,類外初始化

靜態成員函式

所有物件共享同乙個函式

靜態成員函式只能訪問靜態成員變數

**示例1 :**靜態成員變數

class

person

;int person::m_a =10;

int person::m_b =10;

void

test01()

intmain()

**示例2:**靜態成員函式

class

person

static

int m_a;

//靜態成員變數

int m_b;

// private

://靜態成員函式也是有訪問許可權的

static

void

func2()

};int person::m_a =10;

void

test01()

intmain()

C 建構函式 拷貝構造 析構函式

建構函式 constructor 在例項物件時,系統自動呼叫,用來初始化物件的資料成員 建構函式宣告語法 類名 引數列表 建構函式注意點 include include using namespace std class computer 上面的建構函式也可以寫成引數列表初始化的形式 compute...

c 基礎學習 析構函式 拷貝建構函式

字串函式 string類是c 提供的字串類,其主要功能是對字串進行操作。string類定義的變數稱為字串物件,該物件可以直接用字串常量賦值,也可呼叫string類中定義的成員函式。常型別是指使用型別修飾符const說明的型別,常型別的變數或物件的值不能被更新。c 中引入const的目的是為了取代巨集...

C 基礎(一)建構函式 析構函式 拷貝建構函式

在c 中你寫乙個空類,什麼都不做,編譯器會給你生成乙個建構函式,乙個拷貝建構函式,乙個拷貝賦值函式 運算子過載 乙個析構函式,而且是當他們被呼叫的時候才生成。這說明這四個函式的重要 這裡主要說他們其中的三個 c 中的建構函式用來產生物件,他告訴編譯器如何初始化乙個物件,以及其它一些前期工作 相對應的...