virtual 关键字
在C++中,virtual
关键字用于声明一个函数为虚函数,这意味着它可以在派生类中被重写(覆盖)。使用 virtual
的目的是允许通过基类指针或引用调用派生类的函数,这是多态的基础——即同一个函数调用可以表现出多种不同的行为。
当基类声明一个函数为虚函数时,C++ 运行时使用一种称为虚函数表(vtable)的机制来动态决定应调用哪个类的函数。这使得程序在运行时能够根据对象的实际类型来选择正确的函数版本,而不是编译时绑定的类型。
= 0 语法
在 C++ 中,= 0 语法用于将虚函数声明为纯虚函数。这意味着这个函数没有在当前类中实现,必须在派生类中提供实现。这个语法实质上是在告诉编译器和其他开发者,任何派生自该类的类都必须实现这个函数,否则它们也会成为抽象类,不能实例化对象。
一个类如果包含至少一个纯虚函数,则这个类就是抽象类。抽象类不能被实例化,它的主要目的是作为派生类的基础,强制派生类遵循某种设计协议或接口。
扩展
从上面派生出来的类实现其中函数时最好使用关键字 override
,
使用 override
关键字在 C++11 及以后的版本中具有以下好处:
-
明确表示意图
override
关键字明确表示一个函数是意图重写基类中的虚函数。这有助于提高代码的可读性和可维护性,使得其他开发者可以更容易地理解你的代码。 -
编译器检查
更重要的是,override
关键字让编译器知道你的意图是重写基类的一个虚函数。如果基类中没有对应的虚函数声明(可能是因为函数签名不匹配或者基类函数不是虚函数),编译器将报错。这样可以在编译时捕捉到潜在的错误,例如拼写错误或者参数类型不匹配,而不是在运行时表现为错误的行为。 -
保护代码免受未来更改的影响
使用override
也保护了你的代码免受基类接口更改的影响。如果基类的虚函数被重命名或更改了签名,那么派生类中带有override
的函数将无法编译,迫使开发者检查并更新派生类以匹配新的基类接口。
示例
基类:
class IImagePlugin
{
public:
virtual ~IImagePlugin() {}
virtual void Initialize(IHost* host) = 0;
virtual void ProcessImage(ImageData* image) = 0;
virtual void Finalize() = 0;
};
派生类:
class SepiaFilterPlugin : public IImagePlugin
{
public:
void Initialize(IHost* host) override {
// Plugin initialization code here
}
void ProcessImage(ImageData* image) override {
// Apply sepia filter to the image
}
void Finalize() override {
// Cleanup code here
}
};