金庆的专栏

  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  420 随笔 :: 0 文章 :: 454 评论 :: 0 Trackbacks
当心虚函数重载(overloaded-virtual)

(转载请注明来源于金庆的专栏)

为网游万王之王3(KOK3)服务器添加新功能的时候,
发现某个类成员函数应该是const函数, 因为我的const函数要调用该函数,
顺手就加上了const.

再顺便看到该类有好多个明显是getter函数, 所以都加上了const.
编译没错就提交了.

结果没多久测试就发现了新版本的一个错误, 表现在其他功能上,
但由同事纠错后发现是我添加const的后果.

原来添加const的成员函数中, 有一个是virtual函数, 加了const后与子类的函数原型就不符了.
子类的函数成为父类虚函数的一个重载, 使virtual失效, 多态性无法表现出来.
解决方法就是子类的相应虚函数中也添加const.

教训: 更改虚函数原型时, 必须同时更改父类和子类.

gcc中有个-Woverloaded-virtual警告选项, 会报告这种虚函数重载.

我在Makefile中打开了-Woverloaded-virtual, 再次编译时就产生了许多警告.
大多数警告是正确的函数重载, 但还是发现了一个与我相同的错误,
这次是函数参数const有区别, 我发给相关人员处理了.

因为开了-Werror, 所有警告都会造成编译失败,
所以我们不能在Makefile中加入-Woverloaded-virtual警告选项.

代码示例:

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的代码规范中要求所有子类的虚函数中都加上virtual, 是很有道理的.
虽然只要与父类虚函数签名相同, 加不加virtual都是虚函数,
但是以后更改函数签名时, 看到virtual很容易知道它是虚函数, 需要父类子类同时更改.


posted on 2009-05-22 13:59 金庆 阅读(6735) 评论(4)  编辑 收藏 引用 所属分类: 1. C/C++4. Linux/Unix2. 网游开发

评论

# re: 当心虚函数重载(overloaded-virtual) 2009-05-22 14:21 亨德列克
你参与KOK3?期待啊……我玩过KOK1……  回复  更多评论
  

# re: 当心虚函数重载(overloaded-virtual)[未登录] 2009-06-09 20:14 董波
楼主,学习C++和Boost的时候看到了您的很多资料,非常感谢您的无私奉献!
现在大学要毕业了,以后可能没这么多时间像现在一样学习了,呵呵。
感谢楼主!感谢金庆。
您是google的boost翻译组的吗?我看到了您的一些贡献。  回复  更多评论
  

# re: 当心虚函数重载(overloaded-virtual) 2009-06-10 09:13 金庆
@董波
工作了同样要抽时间学习啊。好消息是,工作中的学习不是应付考试的学习。
我是boost翻译小组成员,翻译了2个库:python和signals. 现在还在翻译1.39版中新增的signals2库。  回复  更多评论
  

# re: 当心虚函数重载(overloaded-virtual) 2009-06-15 22:44 董波
@金庆
呵呵,我是说这个名字怎么这么面熟呢?
有时间把asio翻译翻译吧,哈哈。。。
我英语不是很好,简单点的还成,稍微复杂点的句子就迷糊了,呵呵。
asio东拼西凑的看了一些资料,由于没有完整的理解到所有的东西,所以用的时候总是畏首畏尾的,呵呵。  回复  更多评论
  


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理