本文我们学习如何使用C++11特定
override
和final
标识符声明虚方法。
问题描述
与其他类似编程语言不同,C++没有特定的声明接口语法(仅包括纯虚方法的基类),而且如何声明虚方法方式存在不足。在C++中虚方法通过 virtual
关键字声明,但是在派生类中重写虚方法时,virtual
关键字却是可选的,当遇到较大的类或继承关系复杂时会导致混乱,为了确认某个方法是否为虚方法,需要顺着继承关系一致追溯至基类。另外,有时还会遇到虚方法在后续派生类中不再被重写场景,这时仅依赖基类的virtual
关键字则不能满足。
override 和 final 关键字
override
的工作方式非常简单;在虚方法声明或定义中,它确保方法实际上重写了基类虚方法,否则编译器将触发错误。
应该注意的是,override
和final
关键字都是只有在成员方法声明或定义中才有意义的特殊标识符。它们不是保留的关键字,因此可以在程序中作为用户定义的标识符使用。
使用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 // 编译错误
{
};
虽然在已定义的上下文中使用override
和final
都有特殊的意义,但实际上它们不是保留关键字,所以你仍然可以在c++代码中使用它们。这确保了c++ 11之前的代码不会因为使用了这些特殊的标识符而崩溃,当然也不建议使用造成歧义:
class foo
{
int final = 0;
void override() {}
};
总结
本文解释C++虚方法声明方式的灵活性导致存在不足,通过正确使用 override
和 final
标识符可以让声明更清晰、明确。最后也指明这两个关键字可以作为标识符,并不是保留关键字,当然也不建议作为标识符使用。
本文参考链接:https://blog.csdn.net/neweastsun/article/details/123652271