C++ 虚函数
C++ 虚函数
虚函数是基类中可以在派生类中被重写的成员函数。
虚函数是 C++ 多态性 的一个关键部分。它们允许不同的对象对同一个函数调用做出不同的响应。
为什么使用虚函数?
没有 virtual,C++ 会根据指针类型来决定调用哪个函数,而不是实际的对象类型。
有了 virtual,它会检查指针实际指向的对象。
或者更简单地说:
- 没有
virtual:即使对象来自子类,基类函数也会运行。 - 有了
virtual:子类的版本会运行,如您所期望的那样。
没有虚函数的情况
示例(无 virtual 关键字)
class Animal {
public:
void sound() {
cout << "动物声音\n";
}
};
class Dog : public Animal {
public:
void sound() {
cout << "狗吠叫\n";
}
};
int main() {
Animal* a; // 声明一个指向基类 (Animal) 的指针
Dog d; // 创建一个派生类 (Dog) 的对象
a = &d; // 将基类指针指向 Dog 对象
a->sound(); // 使用指针调用 sound() 函数。由于 sound() 不是虚函数,这会调用 Animal 的版本
return 0;
}
尽管 a 指向一个 Dog,它仍然调用 Animal::sound(),因为该函数不是虚函数。
有虚函数的情况
示例(使用 virtual 关键字)
class Animal {
public:
virtual void sound() {
cout << "动物声音\n";
}
};
class Dog : public Animal {
public:
void sound() override {
cout << "狗吠叫\n";
}
};
int main() {
Animal* a;
Dog d;
a = &d;
a->sound(); // 输出:狗吠叫
return 0;
}
现在它按预期工作了!因为 sound() 是虚函数,调用使用了实际对象的函数,而不仅仅是指针类型。
- 仅在基类中使用
virtual - 在派生类中使用
override(可选,但推荐)以提高清晰度
C++ 中的 -> 运算符
您可能想知道为什么我们在上面的例子中使用了 ->。
-> 运算符用于通过指针访问成员(如函数或变量)。
它是 (*pointer).member 的快捷方式:
Animal* a = new Animal(); a->sound(); // 等同于 (*a).sound();
提示:如果您使用的是指向对象的指针,请使用 -> 来访问其成员。