13.1.1 拷貝建構函式
直接初始化:根據引數選擇最匹配的建構函式
拷貝初始化:使用拷貝建構函式或移動建構函式來完成,要求編譯器將右側運算物件拷貝到正在建立的物件中,如果需要的話還要進行型別轉換
foo(const foo&);//宣告拷貝建構函式
有explicit建構函式的物件只能使用直接初始化
如果我們沒有為乙個類定義拷貝建構函式,編譯器會為我們定義乙個。即使我們定義了其他建構函式,編譯器也會為我們合成乙個拷貝建構函式(問題?我們定義了乙個拷貝建構函式,編譯器還會合成嗎?)
13.1.2 拷貝賦值運算子
foo& operator=(const foo&);
11.1.3 析構函式
~foo();
沒有引數,不能被過載,因此乙個類只有乙個析構函式
在析構函式中,首先執行函式體,然後銷毀成員。成員按初始化順序的逆序銷毀。析構部分是隱式的。成員銷毀時發生什麼完全依賴於成員的型別。銷毀類型別的成員需要執行成員自己的析構函式。內建型別沒有析構函式,因此銷毀內建型別成員什麼也不需要做。隱式銷毀乙個內建指標型別的成員不會delete他所指向的物件當指向乙個物件的引用或指標離開作用域時,析構函式不會執行
我們只能對具有合成版本的成員函式使用=default,即,預設建構函式或拷貝控制成員
13.1.6 阻止拷貝
=delete必須出現在函式第一次宣告的時候
本質上,當不可能拷貝、賦值、銷毀類的成員時,類的合成拷貝控制成員就被定義為刪除的
通過宣告但不定義private的拷貝建構函式(這是合法的),我們可以預先阻止任何拷貝該型別物件的企圖
13.2 拷貝控制和資源管理
通常,管理類外資源的類必須定義拷貝控制成員
13.3 交換操作
class hasptr
; inline
void swap(hasptr &lhs, hasptr &rhs)
hasptr& operator=(hasptr rhs)
使用拷貝和交換的賦值運算子是異常安全的,且能正確處理自賦值
自己提供swap是為了避免std::swap交換物件時不必要的記憶體分配,提高效率,通常直接交換指標值
13.6.1 右值引用
一般而言,乙個左值表示式表示的是乙個物件的身份,而乙個右值表示式表示的是物件的值
不能將右值引用繫結到左值
int &&rr=42;
變數都是左值。不能將乙個右值引用繫結到乙個右值引用型別的表示式上
int &&rr=std::move(rr1);//我們可以銷毀乙個移後源的物件,也可以賦予它新值,但是不能使用乙個移後源物件的值。
使用move的**應該使用std::move而不是move,以避免潛在的名字衝突
13.6.2 移動建構函式和移動賦值運算子
strvec::strvec(strvec&& s) noexcept:/*成員初始化器*/
我們必須在類標頭檔案的宣告和定義中都指定noexcept
不加noexcept,會使用拷貝建構函式而不是移動建構函式。
合成的移動操作:如果乙個類定義了自己的拷貝建構函式、拷貝賦值運算子或者析構函式,編譯器就不會為他合成移動建構函式和移動賦值運算子了。只有當乙個類沒有定義任何自己版本的拷貝控制成員,且它的所有資料成員都能移動構造或移動賦值時,編譯器才會為他合成移動建構函式或移動賦值運算子。定義了乙個移動建構函式或移動賦值運算子的類必須也定義自己的拷貝操作,否則這些成員預設地(合成的版本)被定義為刪除的
用拷貝建構函式代替移動狗仔函式幾乎肯定是安全的
拷貝並交換賦值運算子可以同時實現拷貝賦值運算子和移動賦值運算子兩種功能(前提是此類定義了乙個移動建構函式,對右值,函式傳值引數執行移動構造,對左值,執行拷貝構造) 7.
移動迭代器:解引用生成乙個右值引用。通過呼叫標準庫的make_move_iterator函式將普通迭代器轉換為移動迭代器make_move_iterator(vec.begin());
13.6.3 右值引用和成員函式
void push_back(const x&);//拷貝:繫結到任意型別的x
void push_back(x&&);//移動:只能繫結到型別x的可修改的右值
p482頁 講得非常好!
新標準庫類仍然循序想右值賦值,但是,我們可能忘在自己的類中阻止這種做法。我們希望強制左側運算物件(即this指向的物件)是乙個左值。我們指出this的左右值屬性的方式與定義const成員函式相同,即,在引數列表後放置乙個引用限定符。foo &operator=(const foo&) &;//只能向可修改的左值賦值
,引用限定符可以是& 或&&。
foo anothermem() const &;//注意const和&的次序
引用限定符可以區分過載
如果乙個成員函式有引用限定符,則具有相同引數列表的所有版本都必須有引用限定符
C Primer 第9章 知識點回顧
9.2.3 begin和end成員 實際上有兩個名為begin的成員,乙個是const成員,返回const iterator,另乙個是非常量成員,返回iterator,構成過載 auto it a.begin 僅當a是const,it是const iterator 9.2.4 定義和初始化 只有順序...
C Primer 第19章 知識點回顧
19.1控制記憶體分配 new過程 一 operator new標準庫函式,分配原始未構造記憶體 二 編譯器執行相應建構函式 三 返回指標 operator delete釋放記憶體空間 定位new new place address type initializers 呼叫析構函式會銷毀物件,但是不...
C primer 注意的知識點(第 章)
1 從邏輯上來講,size 成員函式似乎應該返回整形數值,或如 2.2節 建議 中所述的無符號整數。但事實上,size 操作返回的是 string size type 型別的值。我們需要對這種型別做一些解釋。string 類型別和許多其他庫型別都定義了一些配套型別 companion type 通過...