当心虚函数重载(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很容易知道它是虚函数, 需要父类子类同时更改.
分享到:
相关推荐
在Windows XP Service Pack 3(XP SP3)环境中,"Overloaded-kernel-for-XPSP3.rar" 提供了一个经过重载的内核,这表明它可能包含了对原始XP内核的修改或扩展,以实现特定的目标。这种内核通常由开发人员使用Windows...
当一个类有多个构造函数,每个函数具有不同的参数列表时,我们称这种情况为构造函数的重载(Overloaded Constructors)。这种特性使得我们可以根据需要以不同的方式创建类的对象,提高了代码的可读性和灵活性。 ...
重载函数(Overloaded Function)是VHDL中的一种基本结构单元,用于描述数字电路的行为。重载函数的基本格式如下所示: ```vhdl function 函数名 (参数列表) return 类型 is -- 函数的描述 begin -- 函数的实现 ...
- **重载函数(Overloaded Functions)**:C++允许函数名相同但参数列表不同的函数存在,这就是重载。通过这种方法,一个函数可以根据传入的不同参数类型执行不同的操作。 - **模板函数(Template Functions)**:...
5. **重载函数(Overloaded Functions)**:C++允许在同一作用域内用相同的名字定义多个函数,只要它们的参数列表不同即可。这是实现方法多态性的一种方式。 6. **默认参数(Default Arguments)**:在定义函数时...
4. 成员函数重载(Overloaded Member Functions):相同名称的函数可以根据不同的参数列表有不同的实现,提供多态性。 ```cpp class MyClass { public: void print(int number) { std::cout ; } void print(std::...
8. 重载函数(Overloaded Functions):函数的重载基于参数列表,包括数量、类型和顺序,返回类型不影响重载。 9. 派生类(Derived Class):派生类可以从一个或多个基类派生,且可以继续派生出新的子类。 10. ...
在 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...
- 虚函数(virtual method)可以在基类中提供默认实现,子类可以选择重写。 ```csharp public abstract class Base { public abstract void AbstractMethod(); public virtual void VirtualMethod() { Console....
文档中提到了一个编译错误:“[Error] call of overloaded 'Tdate()' is ambiguous”,这表明编译器在解析重载构造函数时产生了歧义。这通常是由于没有明确指定调用哪一个构造函数导致的,需要程序员提供明确的构造...
- **常见原因**:尝试重写基类中的虚函数但更改了返回类型或调用约定。 - **解决方法**: - 保持返回类型和调用约定与基类一致。 - 如果需要不同的返回类型,可以考虑使用其他函数名称。 #### 14. error C2660: '...
**描述**:类`B`中覆盖的虚函数`f1`与基类`A`中的`f1`仅在返回类型或调用约定上不同。 **解决方案**: - 确保覆盖函数的返回类型与基类相同。 - 如果需要更改返回类型,则考虑使用不同的函数名。 #### 14. error C...
error C2511: 'reset': overloaded member function 'void(int)' not found in 'B' (重载成员函数 'void(int)' 在 'B' 中未找到) - **错误解释**:试图调用类 `B` 中的重载函数 `reset`,但未找到与参数匹配的函数...
17. **单选题**:为了实现包含多态,派生类需要重新定义基类中的虚函数(Virtual function)。 18. **单选题**:编译时多态性通过函数重载(Overloading)函数实现。 19. **单选题**:C++函数不一定有返回值,例如void...
- 确保子类中覆盖的虚函数具有与基类中相同的返回类型和调用约定。 ##### error C2660: 'SetTimer': function does not take 2 parameters 此错误表示函数参数数量不匹配。 - **解决方案**: - 调整参数数量以...
- **解释**:编译器在类“B”中找不到与预期签名匹配的重载函数“void reset(int)”。 - **解决方案**: - 确认类中是否存在该重载函数。 - 检查函数签名是否匹配。 #### 13. error C2555: 'B::f1': overriding ...
尝试捕获超载该软件包包含重载Try / Catch语句的功能。动机添加自定义错误需要手动检查哪种类型的错误我们收到的是catch块,因为JS没有catch过载。 例如class UserNotFoundError extends Error { // ... Some ...