很多c++新手不明白直接初始化、拷貝初始化,不清楚初始化過程中使用哪個建構函式。在學習過程中,要有基本概念,並且養成正確的認識也是非常重要的。因此整理了本文。
常見錯誤認識1:
1.使用()和使用=定義物件沒什麼區別。(直接初始化、拷貝初始化。)
2.直接初始化使用建構函式。(錯,也可能使用拷貝建構函式。)
3.拷貝初始化使用拷貝建構函式。(錯,也能使用建構函式。)
如果有乙個新物件被定義(即建立了新物件),一定有建構函式被呼叫。
使用直接初始化時,我們實際上要求編譯器使用普通的函式匹配,來提供引數最匹配的建構函式。因此直接初始化可能使用建構函式,也可能使用拷貝建構函式。
簡單理解,用()來定義物件的就為直接初始化。
按字面意思理解即可,將乙個物件給另乙個物件初始化。
簡單理解,用=定義物件的就為拷貝初始化。
注意:拷貝賦值運算子也用在=的情況下,但是在物件已經建立並存在的情況下,只是修改物件的值而已。
而用=拷貝初始化是發生在定義乙個物件的情況下,即物件此前尚未存在。
類定義如下:
#include
#include
class
book
book
(std::string s,
int n)
:name
(s),
sum(n)
book
(const book &b)
:name
(b.name)
,sum
(b.sum)
book &
operator=(
const book &b)
private
: std::string name;
int sum;
};
如果有以下**,判斷,b1~b5初始化時分別使用哪個函式?
book b1;
book b2
("b2");
book b3 = string (
"b3");
cout << endl;
book b4
(b3)
; book b5 = b3;
cout << endl;
b1 =
string
("b1"
);
1、b1:直接初始化。由於未能提供初始值,使用預設的建構函式。(想定義使用預設建構函式的物件,物件名之後不能有括號,即不能寫book b1()。這種寫法意思是定義了乙個叫b1的函式,返回值為book物件。)
2、b2:直接初始化。使用了具有乙個string引數的構造引數。
3、b3:拷貝初始化。使用了具有乙個string引數的建構函式。
在b3初始化時,分為如下兩步:
第一步:使用乙個具有string引數的建構函式將string構造為臨時book類物件。
但是實際上,編譯器會進行優化,可以跳過拷貝、移動建構函式,直接使用建構函式來構造物件,即優化掉了第一步。
4、b4:直接初始化。使用了拷貝建構函式。因為括號中為book類物件,最匹配的是拷貝建構函式。5、b5:拷貝初始化。使用拷貝建構函式。
6、b1: 先使用建構函式將string轉為book類物件,然後將該物件通過賦值運算子來賦值給b1。
測試結果如下:
參考《c++ primer》13.1.1 p441~p442。
c 直接初始化與拷貝初始化
我們常見的幾種初始化的形式 string str1 first 拷貝初始化,編譯器允許把這句話改寫為string str first 但是string類必須有public的拷貝 移動 建構函式 string str2 10,a 直接初始化 string str3 str2 直接初始化 string ...
直接初始化和拷貝初始化
定義 示例 string dots 10,直接初始化 string s dots 直接初始化 string s2 dots 拷貝初始化 string null book 9 999 99999 9 拷貝初始化 string nines string 100,9 拷貝初始化注 直接初始化實際上是要求編...
直接初始化與拷貝 複製 初始化
認識這兩種初始化有助於我們加深對語言的理解,可以更好的優化 我們常見的幾種初始化的形式 string str1 first 拷貝初始化,編譯器允許把這句話改寫為string str first 但是string 類必須有 public 的拷貝 移動 建構函式 string str2 10,a 直接初...