2016年11月24日 星期四

virtual和override和final

http://viml.nchc.org.tw/blog/paper_info.php?CLASS_ID=1&SUB_ID=1&PAPER_ID=547

如網頁上寫的,其實很清楚了

我就講一下virtual的注意地方,其實就是雖然virtual可以寫成虛函式,但是其實有時候型態轉換錯誤,或是不小心存取到虛函式時,還是會出錯,所以我為了避免跳出錯誤訊息,其實就算是用來被繼承而已的虛函式,其實我也會把他實例化(在cpp),也就是寫個他的實體函式,這樣就算錯誤時他也只會執行到空函式,提供給您們參考

總之virtual很好用的,
class CA
{
public:
       virtual void func1(int a)
       {
               ////
               // 其他程式片段
               ////
       }
       virtual void func2(int a)
       {
               ////
               // 其他程式片段
               ////
        }
};

class CB : public CA
{
public:
       void func1(int a) {
               CA::func1(a);
               CA::func2(a);
               ////
               // 其他程式片段
               ////
       }
};

這裡這樣寫的是,如果您繼承後,執行CB的Func1,其實CA的Func1還是存在的如您有寫處理寫在CA的Func1,您可以使用CA::func1(a);順便執行父親class的函式,這是一個小技巧

其實在寫很多繼承架構時,會用到這個,當然其他父class函式也是可以存取的,總之就加CA::其他父class函式,只要您滿足繼承關係(就public,private,protected),要怎樣使用就怎樣使用

例外就簡單講override和final吧,其實連結裡面已經有寫很清楚了,

Override加在virtual函式後面,他會檢查是否有蓋到繼承的class的函式,沒蓋到編譯會出錯,

Fianl則是該函式或是class是最後端點,不可以做繼承用,如果您繼承了,他編譯會出錯

基本上在classic Borland compiler是沒有這個的,要用新的clang c++11 compiler可以編譯過,由於後來我在處理DLL溝通時,在classic Borland compiler(32bit)和clang c++11 compiler(64bit)切換實在麻煩,就是語法上有些差異,要額外處理,因此我都改成clang c++11 compiler(32bit/64bit)了

至於CodeGuard基本上已經棄用了,我在等C++ Builder支援AddressSanitizer再來做偵錯(不確定是否會支援),基本上只要少直接用new指標傳來傳去,基本上不太會會出現沒有delete到的狀況,而且說實在的,其實如果動態產生指標傳來傳去,其實CodeGuard好像也抓不到,所以基本上CodeGuard對我個人用處不是很大(重點CodeGuard好像沒維護了,其實案子一大,有時候跑一跑會程式會出錯,總之感覺用處不大)

而最近其實有測試了Intel Inspector,他在XE10.1 berlin的64bit環境是可以抓記憶體錯誤的(32bit不行),有空可以試試看

沒有留言:

張貼留言