C++11中的override和final关键字是为了增强代码的编译时类型检查和面向对象设计中的继承机制。
override关键字用于显示地表明派生类中的成员函数覆盖了基类中的虚函数。当派生类中的函数与基类中的虚函数签名不同或者没有使用override关键字时,编译器会给出警告或错误提示。这样可以避免因为函数签名不同而无法正确覆盖基类中的虚函数,从而导致程序运行时的错误。
final关键字用于显示地防止在派生类中重载某个函数。如果在一个虚函数上使用了final关键字,那么任何派生类都无法再对该函数进行重载。
当 final 用于类上时,它表示该类是最终类,不能被派生出子类。
class Base final { ... };
当 final 用于成员函数上时,它表示该函数不能被重写
class Base {
public:virtual void foo() final;
};class Derived : public Base {
public:// 以下代码会报错virtual void foo() override;
};
当 final 用于虚函数上时,它表示该虚函数不能被覆盖
class Base {
public:virtual void foo();
};class Derived : public Base {
public:// 以下代码会报错virtual void foo() final;
};
其他:
基类中将虚函数声明为私有函数 和 将虚函数声明为 final 的效果是不同的。
将虚函数声明为私有函数,可以让子类无法直接调用该函数,但子类仍然可以定义一个同名的函数来实现其自己的功能。这种情况下,虚函数的目的是为了供子类重写,但是基类本身并不想让子类直接使用虚函数的实现。
而将虚函数声明为 final,则是为了明确告诉子类,该函数不允许被重写。这是因为基类已经认为该函数已经具备了足够的功能,不需要子类重新实现。同时,final 也可以起到一定的优化作用,因为编译器可以在编译时确定该函数的调用路径,从而提高程序的效率。
此外,将虚函数声明为私有函数并不能完全防止子类重写该函数。子类可以通过其他方式(如友元函数、内联函数等)来访问该函数,并在其内部实现同名函数来达到重写的目的。而将虚函数声明为 final,可以确保子类无法重写该函数,从而保证程序的正确性和安全性。
因此,尽管将虚函数声明为私有函数可以达到一定的效果,但是如果真正想防止子类重写该函数,还是应该使用 final 关键字。