編譯器預設生成的函式

2021-07-10 02:53:16 字數 2331 閱讀 7074

拷貝控制函式包括:拷貝建構函式、拷貝賦值函式、移動建構函式、移動賦值函式、析構函式。

1.建構函式

如果我們沒有定義任何建構函式,編譯器會為我們生成乙個預設的建構函式。

如果定義了,則沒有預設建構函式,即不能以class item來定義物件了。

因此,不管有沒有定義建構函式,最好自己定義下預設建構函式。

2.拷貝建構函式

class foo

foo(const foo&); //拷貝建構函式

};

有以下幾點說明:

1)第乙個引數必須是自身的引用型別,而且幾乎總是乙個const引用。

這裡必須是引用的原因是:拷貝建構函式被用來初始化非引用型別引數,如果不是引用型別,就會無限迴圈。

2)拷貝建構函式一般都會被隱式地使用,因此不應該是explicit的。

關於拷貝初始化與直接初始化:

直接初始化直接呼叫與實參匹配的建構函式(包括拷貝建構函式),拷貝初始化首先使用指定建構函式建立乙個臨時物件,然後使用賦值建構函式將那個臨時物件複製到正在建立的物件。

如果使用等號初始化乙個變數,實際上執行的是拷貝初始化,如果不使用等號,則執行的是直接初始化。拷貝初始化在下面情況下也發生:

1)將乙個物件作為實參傳給乙個非引用型別的形參。

2)從乙個返回型別為非引用型別的函式返回乙個物件。

3)用花括號列表初始化乙個陣列中的元素或乙個聚合類中的成員。

(聚合類:所有成員都是public;沒有定義建構函式;沒有類內初始值;沒有基類,沒有virtual函式。)

3.賦值建構函式

class foo

foo & operator=(const foo&); //賦值建構函式

};

有以下幾點說明:

1)為了與內建型別一直(a=b=c),返回乙個指向其左側運算物件的引用。

2)引數是const引用

4.析構函式

5.move建構函式(c++11)

6.move賦值建構函式(c++11)

補充:1.需要析構函式的類也需要拷貝和賦值操作

class hasptr

~hasptr()

private:

string *ps;

int i;

};

例如,上面這個類,需要析構函式來刪除ps。如果我們沒定義拷貝和賦值操作,預設的拷貝和賦值建構函式會執行下面操作:

#include#include #include using namespace std;

class hasptr

~hasptr()/*

hasptr(const hasptr &hp)*/

private:

string *ps;

int i;

};int main()

上面出現的問題也就是淺拷貝問題。

淺拷貝:在物件拷貝時,只是對物件中的資料成員進行簡單的賦值,如果物件中存在動態成員,即指標,淺拷貝就會讓兩個指標指向同乙個記憶體,會出現問題。

深拷貝:針對成員變數存在指標的情況,不僅僅是簡單的指標賦值,而是重新分配記憶體空間。

2.需要拷貝操作的類也需要賦值操作,反之亦然

例如,乙個類為每個物件分配乙個獨有的、唯一地序號。

3.使用=default可以顯式要求編譯器生成預設版本。其中default在類內宣告時使用,則隱式地宣告為內聯函式,如果在類外定義時使用,則不是內聯函式。

4.阻止拷貝

1)定義刪除的函式

#include#include #include using namespace std;

class nocopy;

int main()

注意:對應刪除了析構函式的類,編譯器不允許定義該型別的變數或建立該類的臨時物件,可以動態分配這種型別的物件,但是不能釋放這些物件。

#include#include #include using namespace std;

class nocopy;

int main()

當不可能拷貝、賦值或銷毀類的成員時,累的預設拷貝控制成員就被定義為刪除的。

2)private拷貝控制

將拷貝建構函式和拷貝賦值函式宣告為private可以阻止拷貝。

補充:取址運算子和取址運算子const

empty *operator&();

const empty*operator&() const;

C 編譯器生成的預設函式

c 編譯器生成的預設函式 話題引入 物件的賦值與複製是如何進行的?他們的區別是什麼?如果乙個空的自定義型別能否執行這些操作?物件賦值 通過 運算子過載 user a 10 b b a 物件複製 呼叫拷貝建構函式 user b user a b 或者 user a b 相當於user a b 也是呼叫...

編譯器生成預設建構函式情況

1 類和物件 當乙個a類有預設建構函式,b類中包含a類物件,並且b類沒有建構函式,那麼編譯器會給b類生成預設建構函式 2 繼承 基類有預設的建構函式,派生類沒有顯示給出建構函式。這種情況下,因為建立派生類物件會呼叫基類的建構函式,所以編譯器認為有必要生成派生類建構函式,所以會生成乙個派生類的建構函式...

編譯器自動生成預設建構函式的情況

在程式設計師沒有為類定義預設建構函式的情況下,c 編譯器在某些情況下會自動生成預設建構函式。1.類中包含的其他有預設建構函式的類的物件 例如 class a private int data public a a a this data 10 class b private a m a int m ...