Skip to main content
 首页 » 编程设计

C++虚函数重载声明最佳实践

2022年07月19日137webabcd

本文我们学习如何使用C++11特定 overridefinal 标识符声明虚方法。

问题描述

与其他类似编程语言不同,C++没有特定的声明接口语法(仅包括纯虚方法的基类),而且如何声明虚方法方式存在不足。在C++中虚方法通过 virtual 关键字声明,但是在派生类中重写虚方法时,virtual 关键字却是可选的,当遇到较大的类或继承关系复杂时会导致混乱,为了确认某个方法是否为虚方法,需要顺着继承关系一致追溯至基类。另外,有时还会遇到虚方法在后续派生类中不再被重写场景,这时仅依赖基类的virtual关键字则不能满足。

override 和 final 关键字

override 的工作方式非常简单;在虚方法声明或定义中,它确保方法实际上重写了基类虚方法,否则编译器将触发错误。

应该注意的是,overridefinal关键字都是只有在成员方法声明或定义中才有意义的特殊标识符。它们不是保留的关键字,因此可以在程序中作为用户定义的标识符使用。

使用override特殊标识符可以帮助编译器检测虚方法不覆盖其他虚方法的情况,情况示例:

class Base 
{ 
public: 
    virtual void foo() {} 
    virtual void bar() {} 
}; 
 
class Derived1 : public Base 
{ 
public: 
    // 为了可读性,使用virtual标识符 
    void foo() override {} 
 
    // 编译错误,基类没有bar(char const)方法 
    virtual void bar(char const c) override {} 
}; 
 

另一个特殊标识符final在成员函数声明或定义中使用,表示该函数是虚函数,不能在派生类中重写。如果派生类试图重写虚函数,编译器会报告错误:

class Derived2 : public Derived1 
{ 
    virtual void foo() final {} 
}; 
 
class Derived3 : public Derived2 
{ 
    virtual void foo() override {} // 产生错误 
}; 

final标识符也可以在类声明中使用,以表明它不能派生:

class Derived4 final : public Derived1 
{ 
    virtual void foo() override {} 
}; 
 
class Derived5 : public Derived4 // 编译错误 
{ 
}; 

虽然在已定义的上下文中使用overridefinal都有特殊的意义,但实际上它们不是保留关键字,所以你仍然可以在c++代码中使用它们。这确保了c++ 11之前的代码不会因为使用了这些特殊的标识符而崩溃,当然也不建议使用造成歧义:

class foo 
{ 
    int final = 0; 
    void override() {} 
}; 

总结

本文解释C++虚方法声明方式的灵活性导致存在不足,通过正确使用 overridefinal 标识符可以让声明更清晰、明确。最后也指明这两个关键字可以作为标识符,并不是保留关键字,当然也不建议作为标识符使用。


本文参考链接:https://blog.csdn.net/neweastsun/article/details/123652271