`
yesjavame
  • 浏览: 712221 次
  • 性别: Icon_minigender_2
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

当心虚函数重载(overloaded-virtual)

阅读更多

当心虚函数重载(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很容易知道它是虚函数, 需要父类子类同时更改.

分享到:
评论

相关推荐

    Overloaded-kernel-for-XPSP3.rar_内核 重载_内核重载_重载内核

    在Windows XP Service Pack 3(XP SP3)环境中,"Overloaded-kernel-for-XPSP3.rar" 提供了一个经过重载的内核,这表明它可能包含了对原始XP内核的修改或扩展,以实现特定的目标。这种内核通常由开发人员使用Windows...

    C++构造函数重载

    当一个类有多个构造函数,每个函数具有不同的参数列表时,我们称这种情况为构造函数的重载(Overloaded Constructors)。这种特性使得我们可以根据需要以不同的方式创建类的对象,提高了代码的可读性和灵活性。 ...

    第9章 VHDL结构与要素.pdf

    重载函数(Overloaded Function)是VHDL中的一种基本结构单元,用于描述数字电路的行为。重载函数的基本格式如下所示: ```vhdl function 函数名 (参数列表) return 类型 is -- 函数的描述 begin -- 函数的实现 ...

    C++常用函数查询器

    - **重载函数(Overloaded Functions)**:C++允许函数名相同但参数列表不同的函数存在,这就是重载。通过这种方法,一个函数可以根据传入的不同参数类型执行不同的操作。 - **模板函数(Template Functions)**:...

    C++函数详解

    5. **重载函数(Overloaded Functions)**:C++允许在同一作用域内用相同的名字定义多个函数,只要它们的参数列表不同即可。这是实现方法多态性的一种方式。 6. **默认参数(Default Arguments)**:在定义函数时...

    C++的具体实现 函数类

    4. 成员函数重载(Overloaded Member Functions):相同名称的函数可以根据不同的参数列表有不同的实现,提供多态性。 ```cpp class MyClass { public: void print(int number) { std::cout ; } void print(std::...

    C++程序设计语言作业题

    8. 重载函数(Overloaded Functions):函数的重载基于参数列表,包括数量、类型和顺序,返回类型不影响重载。 9. 派生类(Derived Class):派生类可以从一个或多个基类派生,且可以继续派生出新的子类。 10. ...

    Scala中使用JSON.toJSONString报错原因分析-解决方案.docx

    在 Scala 中使用 JSON.toJSONString 时,可能会出现ambiguous reference to overloaded definition错误,该错误的原因是由于 JSON.toJSONString 方法的重载导致的。下面对该错误的原因进行分析和解决方案的描述。 ...

    一维动态数组实现的矩阵类

    //--------------------------重载部分-Overloaded Part---------------------------------- CMatrix& operator=(const CMatrix &);//重载=赋值运算符 double& operator()(size_t xr,size_t xc);//重载()运算符,A...

    自定义的矩阵类,内含源码与测试工程

    //--------------------------重载部分-Overloaded Part---------------------------------- CMatrix& operator=(const CMatrix &);//重载=赋值运算符 double& operator()(size_t xr,size_t xc);//重载()运算符,A...

    你必须知道的C#的25个基础概念

    - 虚函数(virtual method)可以在基类中提供默认实现,子类可以选择重写。 ```csharp public abstract class Base { public abstract void AbstractMethod(); public virtual void VirtualMethod() { Console....

    C++期末考试重要程序.pdf

    文档中提到了一个编译错误:“[Error] call of overloaded 'Tdate()' is ambiguous”,这表明编译器在解析重载构造函数时产生了歧义。这通常是由于没有明确指定调用哪一个构造函数导致的,需要程序员提供明确的构造...

    最常见的20种VC++编译错误信息集合

    - **常见原因**:尝试重写基类中的虚函数但更改了返回类型或调用约定。 - **解决方法**: - 保持返回类型和调用约定与基类一致。 - 如果需要不同的返回类型,可以考虑使用其他函数名称。 #### 14. error C2660: '...

    20种VC++编译错误信息

    **描述**:类`B`中覆盖的虚函数`f1`与基类`A`中的`f1`仅在返回类型或调用约定上不同。 **解决方案**: - 确保覆盖函数的返回类型与基类相同。 - 如果需要更改返回类型,则考虑使用不同的函数名。 #### 14. error C...

    常见的21种VC++编译错误信息集合

    error C2511: 'reset': overloaded member function 'void(int)' not found in 'B' (重载成员函数 'void(int)' 在 'B' 中未找到) - **错误解释**:试图调用类 `B` 中的重载函数 `reset`,但未找到与参数匹配的函数...

    C++课后测试满分答案.docx

    17. **单选题**:为了实现包含多态,派生类需要重新定义基类中的虚函数(Virtual function)。 18. **单选题**:编译时多态性通过函数重载(Overloading)函数实现。 19. **单选题**:C++函数不一定有返回值,例如void...

    VC++常见错误一览表

    - 确保子类中覆盖的虚函数具有与基类中相同的返回类型和调用约定。 ##### error C2660: 'SetTimer': function does not take 2 parameters 此错误表示函数参数数量不匹配。 - **解决方案**: - 调整参数数量以...

    最常见的VC20种编译错误

    - **解释**:编译器在类“B”中找不到与预期签名匹配的重载函数“void reset(int)”。 - **解决方案**: - 确认类中是否存在该重载函数。 - 检查函数签名是否匹配。 #### 13. error C2555: 'B::f1': overriding ...

    try-catch-overloaded:该存储库包含用于重载TryCatch语句的TS和JS库

    尝试捕获超载该软件包包含重载Try / Catch语句的功能。动机添加自定义错误需要手动检查哪种类型的错误我们收到的是catch块,因为JS没有catch过载。 例如class UserNotFoundError extends Error { // ... Some ...

Global site tag (gtag.js) - Google Analytics