今天咱們來看看一些在程序中迷惑的寫法,下面的程序想要表達什麼意思呢?ios
#include <iostream> #include <string> using namespace std; template < class T > class Test { public: Test(T t) { cout << "t = " << t << endl; } }; template < class T > void func(T a[], int len) { for(int i=0; i<len; i++) { cout << a[i] << endl; } } int main() { int a[5] = {1, 2, 3, 4, 5}; Test<int> t(5); cout << endl; func(a, 5); return 0; }
咱們在類模板中用 class 來聲明,可是咱們在 main 函數中是用 int 類型來使用的,下來咱們看看這樣的寫法在 C++ 編譯器中支持嗎?編程
咱們看到編譯器編譯經過而且運行成功。那麼咱們不是用的 typename 來聲明的泛指類型的嘛,這怎麼用 class 了呢。這是由於歷史上的一些緣由,早期的 C++ 直接複用 class 關鍵字來定義模板,可是泛型編程針對的不僅是類類型,class 關鍵字的複用使得代碼出現二義性。下來咱們來看看具備二義性的代碼ide
#include <iostream> #include <string> using namespace std; int a = 0; class Test_1 { public: static const int TS = 1; }; class Test_2 { public: struct TS { int value; }; }; template < class T > void test_class() { T::TS * a; // 這便出現了二義性 // 1. 經過泛指類型 T 內部的數據類型 TS 定義指針變量 a (推薦的解讀方式) // 2. 使用泛指類型 T 內部的靜態成員變量 TS 與全局變量 a 進行乘法操做 } int main() { test_class<Test_1>(); test_class<Test_2>(); return 0; }
咱們經過在函數模板指定泛指類型爲 Test_1,即是第 2 種解讀方式,泛指類型爲 Test_2 時,即是第 1 種解讀方式。那麼在這塊是否是就出現了二義性呢?咱們看看編譯結果函數
咱們看到編譯器直接報錯了,若是是一種類型的話,便讓咱們在前前面加上 typename,那麼咱們在模板中加上 typename,看看學習
編譯器又報錯了,它說 Test_1 中沒有這種類型,確定沒有啊,只有一個成員變量而已。咱們註釋掉 Test_1 看看spa
編譯經過了。那麼 typename 誕生的緣由是什麼呢?用來自定義類類型內部的嵌套類型,不一樣類中的同一個標識符可能致使二義性,編譯器沒法直接辨識標識符到底是什麼。typename 的做用有兩個:一、在模板定義中聲明泛指類型;二、明確告訴編譯器其後的標識符爲類型。指針
那麼下面的程序想要表達什麼意思呢?圖片
try...catch 用於分隔正常功能代碼與異常處理代碼,try...catch 能夠直接將函數實分隔爲兩部分。函數聲明和定義時能夠直接指定可能拋出的異常類型,異常聲明成爲函數的一部分能夠提升代碼可讀性。那麼函數異常聲明時有幾個注意事項:一、函數異常聲明是一種與編譯器之間的契約;二、函數聲明異常後就只能拋出聲明的異常,拋出其餘異常將致使程序運行終止,能夠直接經過異常聲明定義無異常函數。編譯器
下來咱們仍是以代碼爲例來進行說明string
#include <iostream> #include <string> using namespace std; int func(int i, int j) throw(int) { if( (0 < j) && (j < 10) ) { return (i + j); } else { throw '0'; } } void test(int i) try { cout << "func(i, i) = " << func(i, i) << endl; } catch(int i) { cout << "Exception: " << i << endl; } catch(...) { cout << "Exception..." << endl; } int main() { test(5); test(10); return 0; }
咱們在 func 函數中異常只聲明瞭 int,而拋出了字符型異常。咱們來看看會致使程序運行終止嘛?
確實致使了程序的運行終止了,注意咱們的程序中還有 catch(...) 都沒能捕捉到 char 類型的異常。那麼咱們在聲明的異常中加上 char 再來看看
程序正常的運行結束了。經過今天對一些迷惑寫法的學習,總結以下:一、class 能夠用來在模板中定義泛指類型(不推薦);二、typename 是能夠消除模板中的二義性;三、try...catch 能夠將函數體分紅 2 部分;四、異常聲明可以提供程序的可讀性。
歡迎你們一塊兒來學習 C++ 語言,能夠加我QQ:243343083。