C 類和物件 物件的初始化和清理

2022-09-08 07:12:08 字數 4955 閱讀 1514

4.2.1 建構函式和析構函式

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

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

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

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

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

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

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

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

函式名稱與類名相同

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

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

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

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

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

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

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

#include using namespace std;

// 物件的初始化和清理

// 1、建構函式 進行初始操作

class person

// 2、析構函式 進行清理操作

// 沒有返回值 不寫 void

// 函式名和類名相同 在名稱前加 ~

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

// 物件在銷毀前 會自動呼叫析構函式,而且只會呼叫一次

~person() };

// 構造和析構都是必須的實現,如果我們自己不提供,編譯器會提供乙個空實現的構造和析構

void test01()

int main()

4.2.2 建構函式的分類及呼叫

兩種分類方式:

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

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

三種呼叫方式:

​ 括號法

​ 顯示法

​ 隱式轉換法

示例:

#include using namespace std;

// 1、建構函式的分類及呼叫

// 分類

// 按照引數分類 無參構造(預設構造)和有參構造

// 按照型別分類 普通構造 拷貝建構函式

class person

person(int a)

// 拷貝建構函式

person(const person& p)

~person()

int age;

};// 呼叫

void tste01()

int main()

4.2.3 拷貝構造函式呼叫時機

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

示例:

#include using namespace std;

// 拷貝構造函式呼叫時機

class person

person(int age)

person(const person& p)

~person()

int m_age;

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

void test01()

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

void dowork(person p)

void test02()

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

person dowork2()

void test03()

int main()

4.2.4 構造函式呼叫規則

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

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

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

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

構造函式呼叫規則如下:

示例:

#include using namespace std;

// 建構函式的呼叫

// 1、建立乙個類,c++編譯器會給每個類都新增至少3個函式

// 預設構造 (空實現)

// 析構函式 (空實現)

// 拷貝構造 (值拷貝)

// 2、如果我們寫了有參建構函式,編譯器就不再提供預設構造,依然提供拷貝構造

// 如果我們寫了拷貝建構函式,編譯器就不再提供其他普通建構函式了

class person

//~person()

// //person(int age)

// person(const person& p)

int m_age;

};//void test01()

//void test02()

int main()

4.2.5 深拷貝與淺拷貝

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

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

深拷貝:在堆區重新申請空間,進行拷貝操作

示例:

#include using namespace std;

// 深拷貝和淺拷貝

class person

person(int age, int height)

// 自己實現拷貝建構函式 解決淺拷貝帶來的問題

person(const person& p)

~person()

cout << "person 的析構構造函式呼叫" << endl;

} int m_age;

int* m_height;

};void test01()

int main()

總結:如果屬性有在堆區開闢的,一定要自己提供拷貝建構函式,防止淺拷貝帶來的問題

4.2.6 初始化列表

作用:

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

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

示例:

#include using namespace std;

// 初始化列表

class person

// 初始化列表初始化屬性

person(int a, int b, int c) : m_a(a), m_b(b), m_c(c)

int m_a;

int m_b;

int m_c;

};void test01()

int main()

4.2.7 類物件作為類成員

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

例如:

class a {}

class b

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

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

示例:

#include using namespace std;

// 類物件作為類成員

// 手機類

class phone

~phone()

// 手機品牌的名稱

string m_pname;

};class person

~person()

// 姓名

string m_name;

// 手機

phone m_phone;

};// 當其他類物件作為本類成員,構造時候先構造類物件,再構造自身,析構順序相反

void test01()

int main()

4.2.8 靜態成員

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

靜態成員分為:

靜態成員函式

示例1 :靜態成員變數

#include using namespace std;

// 靜態成員

class person

;int person::m_a = 100;

int person::m_b = 200;

void test01()

void test02()

int main()

示例2:靜態成員函式

#include using namespace std;

// 靜態成員函式

// 所有物件共享乙個函式

// 靜態函式只能訪問靜態成員

class person

static int m_a; // 靜態成員變數

int m_b; // 非靜態成員變數

private:

static void func2() };

int person::m_a = 0;

// 有兩種訪問方式

void test01()

int main()

C 物件的初始化和清理

物件的初始化和清理也是兩個非常重要的安全問題 乙個物件或者變數沒有初始狀態,對其使用後果是未知 同樣的使用完乙個物件或變數,沒有及時清理,也會造成一定的安全問題 c 利用了建構函式和析構函式解決上述問題,這兩個函式將會被編譯器自動呼叫,完成物件初始化和清理工作。物件的初始化和清理工作是編譯器強制要我...

物件的初始化和清理

建構函式和析構函式 構造 初始化 析構 清理 建構函式的語法 類名 析構函式語法 類名 1.建構函式沒有返回值也不寫void 1.建構函式沒有返回值也不寫void 2.函式名稱與類名相同 2.函式名稱與類名相同,在名稱前加 3.建構函式可以有引數,也可以過載 3.建構函式不可以有引數,不可以過載 4...

類和物件 初始化

一般的訪問許可權修飾符 public protected private 預設,對class修飾一般用public 預設,乙個原始檔中只能有乙個public修飾的類,static 靜態的,static修飾的變數成為靜態變數,是共享的,和static修飾的同名的變數,無論哪乙個改變,其他的也會改變,一...