當(dāng)心虛函數(shù)重載(overloaded-virtual)
(轉(zhuǎn)載請注明來源于金慶的專欄)
為網(wǎng)游萬王之王3(KOK3)服務(wù)器添加新功能的時(shí)候,
發(fā)現(xiàn)某個(gè)類成員函數(shù)應(yīng)該是const函數(shù), 因?yàn)槲业腸onst函數(shù)要調(diào)用該函數(shù),
順手就加上了const.
再順便看到該類有好多個(gè)明顯是getter函數(shù), 所以都加上了const.
編譯沒錯(cuò)就提交了.
結(jié)果沒多久測試就發(fā)現(xiàn)了新版本的一個(gè)錯(cuò)誤, 表現(xiàn)在其他功能上,
但由同事糾錯(cuò)后發(fā)現(xiàn)是我添加const的后果.
原來添加const的成員函數(shù)中, 有一個(gè)是virtual函數(shù), 加了const后與子類的函數(shù)原型就不符了.
子類的函數(shù)成為父類虛函數(shù)的一個(gè)重載, 使virtual失效, 多態(tài)性無法表現(xiàn)出來.
解決方法就是子類的相應(yīng)虛函數(shù)中也添加const.
教訓(xùn): 更改虛函數(shù)原型時(shí), 必須同時(shí)更改父類和子類.
gcc中有個(gè)-Woverloaded-virtual警告選項(xiàng), 會報(bào)告這種虛函數(shù)重載.
我在Makefile中打開了-Woverloaded-virtual, 再次編譯時(shí)就產(chǎn)生了許多警告.
大多數(shù)警告是正確的函數(shù)重載, 但還是發(fā)現(xiàn)了一個(gè)與我相同的錯(cuò)誤,
這次是函數(shù)參數(shù)const有區(qū)別, 我發(fā)給相關(guān)人員處理了.
因?yàn)殚_了-Werror, 所有警告都會造成編譯失敗,
所以我們不能在Makefile中加入-Woverloaded-virtual警告選項(xiàng).
代碼示例:
class A
{
virtual void f() {};
};
class B : public A
{
virtual void f() const {};
};
int main()
{
return 0;
}
$ g++ main.cpp -Woverloaded-virtual
main.cpp:3: warning: `virtual void A::f()' was hidden
main.cpp:8: warning: by `virtual void B::f() const'
Google的代碼規(guī)范中要求所有子類的虛函數(shù)中都加上virtual, 是很有道理的.
雖然只要與父類虛函數(shù)簽名相同, 加不加virtual都是虛函數(shù),
但是以后更改函數(shù)簽名時(shí), 看到virtual很容易知道它是虛函數(shù), 需要父類子類同時(shí)更改.
(轉(zhuǎn)載請注明來源于金慶的專欄)
為網(wǎng)游萬王之王3(KOK3)服務(wù)器添加新功能的時(shí)候,
發(fā)現(xiàn)某個(gè)類成員函數(shù)應(yīng)該是const函數(shù), 因?yàn)槲业腸onst函數(shù)要調(diào)用該函數(shù),
順手就加上了const.
再順便看到該類有好多個(gè)明顯是getter函數(shù), 所以都加上了const.
編譯沒錯(cuò)就提交了.
結(jié)果沒多久測試就發(fā)現(xiàn)了新版本的一個(gè)錯(cuò)誤, 表現(xiàn)在其他功能上,
但由同事糾錯(cuò)后發(fā)現(xiàn)是我添加const的后果.
原來添加const的成員函數(shù)中, 有一個(gè)是virtual函數(shù), 加了const后與子類的函數(shù)原型就不符了.
子類的函數(shù)成為父類虛函數(shù)的一個(gè)重載, 使virtual失效, 多態(tài)性無法表現(xiàn)出來.
解決方法就是子類的相應(yīng)虛函數(shù)中也添加const.
教訓(xùn): 更改虛函數(shù)原型時(shí), 必須同時(shí)更改父類和子類.
gcc中有個(gè)-Woverloaded-virtual警告選項(xiàng), 會報(bào)告這種虛函數(shù)重載.
我在Makefile中打開了-Woverloaded-virtual, 再次編譯時(shí)就產(chǎn)生了許多警告.
大多數(shù)警告是正確的函數(shù)重載, 但還是發(fā)現(xiàn)了一個(gè)與我相同的錯(cuò)誤,
這次是函數(shù)參數(shù)const有區(qū)別, 我發(fā)給相關(guān)人員處理了.
因?yàn)殚_了-Werror, 所有警告都會造成編譯失敗,
所以我們不能在Makefile中加入-Woverloaded-virtual警告選項(xiàng).
代碼示例:
class A
{
virtual void f() {};
};
class B : public A
{
virtual void f() const {};
};
int main()
{
return 0;
}
$ g++ main.cpp -Woverloaded-virtual
main.cpp:3: warning: `virtual void A::f()' was hidden
main.cpp:8: warning: by `virtual void B::f() const'
Google的代碼規(guī)范中要求所有子類的虛函數(shù)中都加上virtual, 是很有道理的.
雖然只要與父類虛函數(shù)簽名相同, 加不加virtual都是虛函數(shù),
但是以后更改函數(shù)簽名時(shí), 看到virtual很容易知道它是虛函數(shù), 需要父類子類同時(shí)更改.
posted on 2009-05-22 13:59 金慶 閱讀(7185) 評論(4) 編輯 收藏 引用 所屬分類: 1. C/C++ 、4. Linux/Unix 、2. 網(wǎng)游開發(fā)


