【深入理解C++11 筆記】——1 保證穩定性和兼容性

靜態斷言 static_assert

關於斷言的個人理解

先說一下爲什麼要使用斷言。在第一次見到斷言時就很疑惑,爲什麼要使用斷言,比如指針爲NULL(assert(ptr!=NULL) ),可以先判斷是否爲NULL然後返回嘛,可以用異常機制包起來嘛。

目前的理解是斷言就是爲了檢查源碼邏輯而存在的,跟其它檢錯機制有些目的上的差別。比如在一個類中寫了一個mynew()函數,和一個mydelete(),對某個私有指針變量賦值。此處有個不變的邏輯是必須先調用一個mynew(),才能再執行一個mydelete()。如果我只寫個幾千來行不到十個類的項目,我可能有這個自信能保證不會用錯。但是代碼規模再大一些的話,這個自信程度就要縮水了。

回到第一段的問題,這個時候用判斷返回有什麼問題,如果這麼做的話的確保證了代碼不會運行錯誤,但是其實隱藏了我此處的邏輯錯誤必須先調用一個mynew(),才能再執行一個mydelete()*,顯然我沒有按照這個邏輯執行纔會出現錯誤,此時直接判斷返回會掩蓋掉邏輯問題(日誌另說),因爲這個錯誤可能是由其他邏輯錯誤導致的子問題,我需要做的是檢查源碼,而不是忽略這個問題。

而使用異常處理,當然也不會讓程序崩潰,但是對用戶來說他是沒辦法解決問題的,用戶沒辦法去修改代碼裏面的邏輯問題,讓這個內存得到正確的釋放。異常處理適用於處理邏輯上可能發生的“錯誤”,比如用戶沒有按照你要求的順序操作等。

總結一下斷言是給程序員自檢邏輯時候用的(排除邏輯上不可能出現的狀態,如果出現了,你的代碼邏輯有問題),不是給用戶用的,也不是用來檢查輸入正確性的。還有日誌如果這麼使用的話,其實和斷言的作用一樣,不過斷言是在編寫時候使用,而日誌一般是項目發佈後,用來檢測錯誤和運行狀態的。

static_assert

assert是在運行時檢查的,如果代碼沒有運行到你寫那部分的話,自然也就沒有用到這句斷言。 static_assert 則是在編譯期間調用,可以使用在函數內或函數體外(建議)。 顯然由於其是在編譯期間使用,所以裏面填寫的表達式必然無法使用變量,舉個簡單例子

assert_static(sizeof(int)!=4,"該程序需要運行在32位機上"); //正確寫法
int n=10;
assert_static(n>0,"整數n應該大於0"); //錯誤寫法,不要使用變量

其他

1.書中這節給出的枚舉類(按位定義)判斷重複的小技巧可以記一下(所以枚舉變量取或和最大標誌判斷是否相等)
2.斷言頭文件爲 #include<cassert>

快速初始化成員變量

vs2012沒有支持。

非靜態成員的sizeof

class Dog{
public:
     int age;
};
void main(){
   cout<<sizeof(Dog::age)<<endl; //C++ 11 支持 c++98不支持
   cout<<sizeof((People*)0->age)<<endl; //c++98中的技巧  空指針“實例化”一個對象
}

friend語法

略微調整,友元類聲明是不需要加class關鍵字了。導致可以寫出以下的模板類:

temple<typename T> class HelloClass{
public :
     friend T;
private:
     //其他內容...
}

有什麼用? 我可以指定任意“好友”類來隨便玩弄我的私有變量了[doge],書中解釋是可以方便測試,私有變量直接”點“出來,總是比寫一堆getter,setter方法來的方便(特別是你的IDE沒辦法自動生成的時候…)。而發表版本可以傳入一個int之類的內置類型時,這句話友元聲明就無效了。

final/override 關鍵字

1.final關鍵字可以終止子類繼續重載虛函數,“爸爸的定的規矩不是你能改的”父類如是說。

class Base{
  virtual void fun() = 0; //純虛函數
  virtual void fun1();
};

clase Child1:public Base{
      void fun() final; //在別處實現
};

clase Child11:public Child1{
      void fun(); //編譯不通過
      void fun11( ) override;
};

2.override
明確的指出了重載操作。比如上例中的孫子Child想重載fun1,結果手抖多打個1,變成fun11。編譯時會說你這不是重載不給過。如果沒有這個關鍵字的話,編譯過了,但其實並沒有重載fun1而是定義一個新函數fun11,調用fun1的時候其實調用的是父類(或往上實現了該方法的類)的函數內容,導致莫名其妙的問題出現。除了名字拼錯外,還有添加參數等,反正不是重載但是加了override關鍵字的都是錯、錯、錯。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章