拷貝控制操作基本概念:
拷貝定義了當用同型別的另乙個物件初始化本物件時做什麼。
賦值定義了將乙個物件賦予同型別的另乙個物件時做什麼。
折構定義了當此型別物件銷毀時做什麼。
拷貝建構函式:如果乙個建構函式的第乙個引數是自身型別的引用,且任何額外引數都有預設值,則此建構函式是拷貝建構函式。
合成拷貝函式:如果我們沒有為類定義拷貝建構函式,編譯器會為我們定義乙個。編譯器會從指定物件中依次將每個非static成員拷貝到正在建立的物件當中。
class a
直接初始化是編譯器使用普通函式匹配,而拷貝初始化通常使用拷貝建構函式來完成。拷貝初始化不僅在我們用=定義變數時會發生,下列情況也會發生:
(1)將乙個物件作為實參傳遞給乙個非引用型別的形參
(2)從乙個返回型別為非引用型別的函式返回乙個物件
(3)用花括號列表初始化乙個陣列的元素或乙個聚合類的成員
#include
#include
class a
//直接初始化
a(const a&a):i(a.i),s(a.s) //拷貝初始化
private:
int i;
std::string s;
};int main()
拷貝賦值運算子是通過過載運算子來實現的。過載運算子的引數表示運算子的物件。如果乙個運算子是乙個成員函式,其左側運算物件就繫結到隱式的 this引數。
如果乙個類為定義自己的拷貝賦值運算子,則編譯器會為其生成乙個合成拷貝賦值運算子。運算過程與拷貝建構函式相似。
class a
折構函式釋放物件使用資源,並銷毀物件的非static資料成員。在乙個折構函式中,首先執行函式體,然後銷毀成員。成員按初始化順序的逆序銷毀。成員在銷毀時發生什麼完全依賴於成員的型別。折構函式體本身並不直接銷毀成員,成員是在折構函式體之後隱含的折構階段被銷毀的。特別注意,當指向乙個物件的引用或指標離開作用域時,折構函式不會執行。
class
a
折構函式呼叫於:
(1)變數離開其作用域時被銷毀
(2)當乙個物件被銷毀時,其成員被銷毀
(3)容器(無論是標準庫容器還是陣列)被銷毀時,其元素被銷毀
(4)對於動態分配的物件,當對指向它的指標應用delete運算子被銷毀
(5)對於臨時物件,當建立它的完整表示式結束時被銷毀。
*三/五 法則(1)當我們決定乙個類是否需要定義自己版本的拷貝控制成員時,乙個基本原則是首先確定這個類是否需要乙個折構函式。如果乙個類需要乙個折構函式,我們幾乎可以確定它也需要乙個拷貝建構函式和乙個拷貝賦值運算子。
(2)如果乙個類需要乙個拷貝建構函式,幾乎可以確定它也需要乙個拷貝賦值運算子,反之亦然。而無論是需要拷貝建構函式還是需要拷貝賦值運算子都不必然意味著也需要折構函式。
#include
class numbered
numbered(const numbered& n)
int mysn;
static
int unique;
};int numbered::unique = 10;
void f(numbered s)
int main()
我們可以通過將拷貝控制成員定義成=default來顯式的要求編譯器生成合成的版本。同時,在c++11標準中,我們可以通過將拷貝建構函式和拷貝賦值運算子定義為刪除的函式來阻止拷貝。但是需要注意的是,折構函式不能是刪除的成員。對於折構函式已刪除的型別,不能定義該型別的變數或釋放指向該型別動態分配物件的指標。本質上,當不可能拷貝、賦值或銷毀類的成員時,類的合成拷貝控制成員就被定義為刪除的。
struct nocopy
類的拷貝 賦值與銷毀
拷貝建構函式 拷貝賦值運算子 移動建構函式 移動賦值運算子 析構函式 當定義乙個類時,我們顯式和隱式地指定在此型別物件的拷貝 移動 賦值和銷毀時做些什麼。而乙個類通過定義上述五種特殊的成員函式來控制這些操作。拷貝和移動建構函式定義了當同型別的另乙個物件初始化本物件時做什麼。拷貝和移動賦值運算子定義了...
c 中類的拷貝 移動 賦值 銷毀
第一次看c primer時拷貝控制這章完全沒看明白,只是很粗略地過了一遍。時隔一年,具備了一定的工程經驗後,再次看這一章對於類的拷貝構造 賦值函式 移動構造 賦值函式以及析構函式有了完全不一樣的認識,在部落格裡記錄一下,c primer每看一遍都會有不同的收穫倒真不是亂說。拷貝建構函式第乙個引數必須...
python bomb 拷貝與賦值
變數 id 在記憶體中的儲存位置,id a value type 資料型別 判斷資料型別和值 is 判斷id,資料型別和值 li 1,1 6 li1 li 直接賦值,兩者滿足 is li1 1,1 6 id li 140492002190728 id li1 140492002190728 li i...