1# warning: ... will be initialized after... / ... warning: when initialized here [1][2]
樣本:
class foo { //declaration int i; int j; public: //constructor & its initializer foo(int val): j(val), i(j) {} };
此樣本foo類編譯時間就將出現上面的警告資訊。
C++規定:建構函式初始化列表(constructor's initializer)中,編譯器對成員初化的實際順序是由成員的聲明/定義順序決定的,而與初始化列表中成員的排列順序無關。在這個樣本中,聲明的順序是先i後j,那麼按根據這個規定,編譯器也會先初始化i,再初始化j。這樣上面的樣本
foo(int val): j(val), i(j) {}在編譯過程中首先就是用一個還未初始化的成員j來初始化成員i,這當然會給程式帶來bug。所以,編譯器友好地給出了上面那條警告資訊。 解決辦法自然是調整初始化順序,與聲明順序一致:
foo(int val): i(val), j(val) {}
Ref.:[1] C++ Primer 中文版 第4版P389[2]
Stackoverflow.com
2# waring: virtual … was hidden by … [3][4][5]樣本:
class Base { public: virtual int fcn(); }; class Derive:public Base { public: // For clearing the warning, uncomment: //using Base::fcn; // However, it's not a good idea to do this (using declaration) if this codes are in any header file. // Or, uncomment: //int fcn(); int fcn(int); }; int main() { std::cout<<"Yeah\n"; return 0; }編譯時間,如果g++ 或Makefile中加了警告選項:-Woverloaded-virtual,則會出現上面那條的警告資訊。 如:$ g++ overloadBaseMember.cc -Woverloaded-virtual
overloadBaseMember.cc:33: warning: `virtual int Base::fcn()' was hidden
overloadBaseMember.cc:43: warning: by `int Derive1::fcn(int)'這是因為衍生類別Derive在繼承基類Base後,其類範圍內重載了基類中的虛函數fcn,那麼在此範圍內原先基類的fcn()函數將被屏蔽/不可見。解決辦法是在衍生類別中使用using聲明(using declaration)來重新聲明基類中所有名為fcn的函數(9行),這樣使其可見。但此法建議不要用在標頭檔中;另一種辦法是在衍生類別Derive中直接重定義Base類中的fcn()函數(12行)。當然,你要乾脆去掉 -Woverloaded-virtual 選項來忽略這類警告,那也是可以的。至於這樣做有什麼風險,以及C++為什麼要預留這種警告?遺憾本君也未弄清,待後續文章更新中再作理解。(亦盼大俠指點迷津)Ref.:[3] C++ Primer 中文版 第4版P501[4]
stackoverflow.com[5]
當心虛函數重載(overloaded-virtual) by 金慶
3# warning: statement has no effect樣本:
int i=0, N=100;for( i; i < N; i++) {}
正確樣本:
int i=0, N=100;for( ; i < N; i++) {}
//orfor(i=0; i<N; i++) {}要麼就必須對for迴圈的第一個參數做點什麼(定義、初始化/賦值),要麼就空著不傳第一個參數。否則,將出現3#的警告資訊。