读书人

重写虚函数返回参数有差异解决方法

发布时间: 2012-04-09 13:41:25 作者: rapoo

重写虚函数返回参数有差异
这是一个The Ultimate Toolbox开源程序中的问题
有类
class OX_CLASS_DECL COXMenuBar : public COXCoolToolBar /*COXCoolToolBar继承与CToolBar*/
{
....
....
public:
HMENU GetMenu() const
{
ASSERT(::IsWindow(GetSafeHwnd()));
return m_hMenu;
}
....
....
}

本来在05下很正常,今天拿到08下报错:
error C2555: “COXMenuBar::GetMenu”: 重写虚函数返回类型有差异,且不是来自“CWnd::GetMenu”的协变

后来我找了下发现如下MFC函数:
CMenu* CWnd::GetMenu() const;

我理解08的错误 首先CWnd::GetMenu()不是虚函数,那么 COXMenuBar::GetMenu()只能重载或者覆盖父类CWnd::GetMenu()。

而结果是重载的话 参数形式完全相同(都没有参数)所以不是重载,覆盖的话返回类型不同 所以08报错!

但问题是 05 为什么就ok了呢?


[解决办法]
首先只有返回值不一样的函数是不合法的,在有的编译器容忍这种错误,只能说它不严格。
至于错误信息,很可能只是错误信息表达不准确。在错误情况下,有时编译器报了一些偏差信息也是可能的,这只是编译器对错误情况分类不够仔细之故!在很多情况下,在派生类重写基类函数,多是虚函数,也许这是分类成虚函数的原因

探讨
引用:
引用:
费解了,为什么08不可以呢?谁能帮我解释一下error 是什么意思呀?
重写虚函数返回类型有差异? 这压根也没个虚函数啊!

[解决办法]
觉得楼主偏重于错误信息的具体解释,而不重自己代码的问题。错误信息只是辅助性的东西,最终做判断的是程序员。如果编译器啥都做完了,那编译器也太完美了,不过完美的编译器我还是没见过
[解决办法]
同时使用 vs2005 和 vs2008 的飘过
这个问题的原因是 vs2005 和 vs2008 中的 CWnd::GetMenu 函数的定义不一样

vs2005:
CMenu* CWnd::GetMenu() const;

而vs2008中
virtual CMenu* GetMenu() const;

看出来区别了吧
vs2005是普通函数 vs2008是虚函数,

这就导致了 05 和 08 编译上的不同

HMENU COXMenuBar::GetMenu() const

05:
COXMenuBar::GetMenu 就是一个普通函数,和父类中的函数没有关系,该函数隐藏了父类中的 GetMenu

08:
COXMenuBar::GetMenu 因为函数名与参数列表都与父类中的虚函数相同,因此被判定为是虚函数改写
但返回值的类型与父类中的不同,因此报错

读书人网 >VC/MFC

热点推荐