拷貝控制函式包括:拷貝建構函式、拷貝賦值函式、移動建構函式、移動賦值函式、析構函式。
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.需要析構函式的類也需要拷貝和賦值操作
例如,上面這個類,需要析構函式來刪除ps。如果我們沒定義拷貝和賦值操作,預設的拷貝和賦值建構函式會執行下面操作:class hasptr
~hasptr()
private:
string *ps;
int i;
};
上面出現的問題也就是淺拷貝問題。#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 ...