现代C++中的显式虚函数重载是通过override
和final
关键字实现的,这两个关键字提高了代码的清晰度和安全性。override
确保子类中的函数确实重写了基类中的虚函数,而final
则防止进一步的重写。这些关键字帮助捕获编程时的错误,如拼写错误或不匹配的函数签名。
1. 使用override
显式声明重写
使用override
关键字可以显式地指明一个成员函数重写了基类的虚函数。如果标记为override
的函数没有匹配基类的虚函数,编译器将报错。
#include <iostream>
class Base {
public:
virtual void func() {
std::cout << "Base function" << std::endl;
}
};
class Derived : public Base {
public:
void func() override { // 明确表示这个函数是重写的
std::cout << "Derived function" << std::endl;
}
};
void useOverride() {
Derived d;
d.func(); // 输出: Derived function
}
2. 使用final
阻止进一步的重写
final
关键字可以阻止继承类重写特定的虚函数。如果尝试重写标记为final
的函数,编译器将报错。
#include <iostream>
class Base {
public:
virtual void func() final { // 阻止进一步重写该函数
std::cout << "Base function" << std::endl;
}
};
class Derived : public Base {
public:
// void func() override { // 尝试重写,将引发编译错误
// std::cout << "Derived function" << std::endl;
// }
};
void useFinal() {
Base b;
b.func(); // 输出: Base function
}
3. 类级别的final
使用
final
关键字不仅可以用于虚函数,还可以用于类。如果一个类被标记为final
,它不能被继承。
class Base final { // 标记为final,阻止进一步继承
public:
virtual void func() {
std::cout << "Base function" << std::endl;
}
};
// class Derived : public Base { // 尝试继承Base,将引发编译错误
// public:
// void func() override {
// std::cout << "Derived function" << std::endl;
// }
// };
void useClassFinal() {
Base b;
b.func(); // 输出: Base function
}
4. override
和构造函数
需要注意的是,构造函数不能被标记为override
,因为构造函数不是可以被继承的成员函数。
class Base {
public:
virtual void func() {
std::cout << "Base function" << std::endl;
}
};
class Derived : public Base {
public:
// Derived() override { } // 错误: 构造函数不能被标记为override
void func() override {
std::cout << "Derived function" << std::endl;
}
};
void constructorOverride() {
Derived d;
d.func(); // 输出: Derived function
}