8. 顯式轉換操作符
c++中的explicit關鍵字只能用於修飾只有乙個引數的類建構函式, 它的作用是表明該建構函式是顯式的, 而非隱式的, 跟它相對應的另乙個關鍵字是implicit, 意思是隱藏的,類建構函式預設情況下即宣告為implicit(隱式)。
class teststring
char m_defchar = '0';
int m_len = 10;
char* m_data = nullptr;
};void showstr(teststring str)
int main()
在 c++11 中,標準將 explicit 的使用範圍擴充套件到了自定義的型別轉換操作符上,以支援所謂的 「顯示型別轉換」。explicit 關鍵字作用於型別轉換操作符上,意味著只有在直接構造目標型別或顯式型別轉換的時候可以使用該型別。
9. 初始化列表
9.1 普通變數
在 c++11 中,自動變數和全域性變數的初始化在 c++11 中被豐富了。程式設計師可以使用以下幾種形式完成初始化工作:
而後兩種形式也可以用於獲取堆記憶體 new 操作符中, 比如:
int* i = new int(1);
double* d = new double;
9.2 容器也支援列表初始化vectorv;
mapm = , };
9.3 自定義型別使用列表初始化
標準模板庫中容器對初始化列表的支援源自 標頭檔案,並且宣告乙個以 initializer_list模板類為引數的建構函式,同樣可以使得自定義的類使用列表初始化。
#include #include #include #include enum gender ;
class people
}private:
vector> m_data;
};void test()
, };
}
同樣的,函式的引數列表也可以使用初始化列表。
#include #include #include #include void func(initializer_listiv)
cout << endl;
};void test()
); func();
}
9.4. 使用列表初始化,可以防止型別收窄
型別收窄一般指一些可以使得資料比哪壺啊或者精度丟失的隱式型別轉換。可能導致型別收窄的典型情況如下:
const int x = 1024;
const int y = 10;
char a = x; //c++98 寫法, 收窄,但可以通過編譯,編譯器警告
char* b = new char(1024); //c++98 寫法, 收窄,但可以通過編譯,編譯器警告
//char c = ; //收窄, 無法通過編譯
char d = ; //未收窄,可以通過編譯
//unsigned char e; //收窄, 無法通過編譯
float f; //未收窄,可以通過編譯
//int g; //收窄, 無法通過編譯
float h = 1.2l; //未收窄,可以通過編譯
10. pod型別
pod 是英文中 plain old data 的縮寫。通常用於說明乙個型別的屬性,尤其是使用者自定義型別的屬性。plain 表示了 pod 是個普通的型別,在 c++ 中常見的都是這樣的屬性,而不像一些存在著虛函式虛繼承的型別那麼特別。而 old 則體現了器與 c 的相容性,比如可以用最老的 memcpy() 函式進行複製, 使用 memset() 進行初始化等。當然,這樣的描述都太過籠統,具體地, c++11 將 pod 劃分成兩個基本概念的合集,即:平凡的(trivial)和標準布局的(standard layout)。
我們先來看一下平凡的定義。通常情況下,乙個平凡的類或者結構體應該符合以下定義:
以上 4 點雖然看似複雜,不過在 c++11 中,我們可以通過一些輔助的類模板來幫助我們進行以上屬性的判斷。
//template struct std::is_trivial;
struct trivial1 {};
struct trivial2
;struct nontrivial1
int c;
};void test()
pod 包含的另外乙個概念是標準布局。標準布局的類或者結構體應該符合以下定義:
(1)所有非靜態成員有相同的訪問許可權(public、private、protected)
//成員 a 與成員 b 擁有不同的訪問許可權,因此該結構體不是標準布局
//如果去掉 private 關鍵字的話,那麼該結構體就符合標準布局的定義了
struct test
(2)在類或者結構體繼承時,滿足以下兩種情況之一:
(3)類中第乙個非靜態成員的型別與其基類不同
(4)沒有虛函式和虛基類
(5)所有非靜態資料成員均符合標準布局型別,其基類也符合標準布局。這是乙個遞迴的定義。
以上 5 點構成了標準布局的含義,最為重要的應該是前兩條。
struct b1{};
struct b2{};
struct d1 : b1
;struct d2 : b1
;int main()
那麼使用 pod 用什麼好處呢?
(1)位元組賦值,**中我們可以安全地使用 memset 和 memcpy 對 pod 型別進行初始化和拷貝等操作。
(2)提供對 c 記憶體布局相容。 c++ 程式設計師可以與 c 函式進行相互操作,因為 pod 型別的資料在 c 與 c++ 間的操作總是安全的。
(3)保證了靜態初始化的安全有效。靜態初始化在很多時候能夠提供程式的效能,而 pod 型別的物件初始化往往更加簡單。
11. 非受限聯合體(略)
12. 使用者自定義字面值(略)
13. 內聯名字空間(略)
14. 模板的別名
在 c++98 中, 使用 typedef 為型別定義別名。在 c++11 中使用 using 同樣也可以定義型別的別名。
#include #include using namespace std;
void test()
使用模板程式設計時, using 的語法比 typedef 更靈活。
//這裡我們模板式地使用了 using 關鍵字, 將 std::map定義為了乙個 mapstring 型別,之後我們還可以使用型別引數對 mapstring 進行型別的例項化,而使用 typedef 將無法達到這樣的效果。
templateusing mapstring = std::map;
mapstringnumberstring;
15. 一般化的 sfinea 規則
在 c++ 模板中有一條著名的規則, 即 sfinea - substitution failure is not an error,中文直譯即為「匹配失敗不是錯誤」。更為確切的說,這條規則表示的是對過載的模板的引數進行展開的時候,如果展開導致了一些不匹配,編譯器並不會報錯。
C 一本通 1 1 練習 3 線段
一本通題庫 1429 libreoj 10007 vjudge 在乙個數軸上有n nn條線段,現選取其中k kk條線段使得這k kk條線段兩兩沒有重合部分,問最大的k kk為多少?第一行為乙個正整數n nn,下面n nn行每行2 22個數字a ia i ai b ib i bi 描述每條線段。輸出檔...
C 一本通 1 1 練習 1 數列極差
一本通題庫 1427 libreoj 10005 vjudge 注意 一本通題庫和libreoj題意相同,但輸入格式不同。以一本通題庫為準。在黑板上寫了n nn個正整數作成的乙個數列,進行如下操作 每一次擦去其中的兩個數a aa和b bb,然後在數列中加入乙個數a b 1 a b 1 a b 1,如...
C 一本通 1 1 例 5 智力大衝浪
一本通題庫 1426 libreoj 10004 vjudge 小偉報名參加 電視台的智力大衝浪節目。本次挑戰賽吸引了眾多參賽者,主持人為了表彰大家的勇氣,先獎勵每個參賽者m mm元。先不要太高興!因為這些錢還不一定都是你的。接下來主持人宣布了比賽規則 首先,比賽時間分為n個時段 n 500 n 5...