在 C++ 编程中,虚函数是实现多态性的关键机制,它为面向对象程序设计带来了极大的灵活性和可扩展性。
在类的成员函数声明前加上关键字 virtual
,即可将该函数定义为虚函数。例如:
class Animal {
public:
virtual void makeSound() {
cout << "Some generic animal sound" << endl;
}
};
虚函数允许在派生类中重新定义(覆盖)基类中的同名函数,并且通过基类指针或引用调用该函数时,能够根据指针或引用实际指向的对象类型来动态决定调用哪个类(基类或派生类)中的函数实现,从而实现多态性。
假设有如下代码:
class Animal {
public:
virtual void makeSound() {
cout << "Some generic animal sound" << endl;
}
};
class Dog : public Animal {
public:
void makeSound() override {
cout << "Woof!" << endl;
}
};
class Cat : public Animal {
public:
void makeSound() override {
cout << "Meow!" << endl;
}
};
以及对应的多态实现代码:
Animal* animal1 = new Dog();
Animal* animal2 = new Cat();
animal1->makeSound();
animal2->makeSound();
delete animal1;
delete animal2;
Animal* animal1 = new Dog();
时,我们创建了一个 Dog
类的对象,但通过一个 Animal*
类型的指针 animal1
来指向它。同样,Animal* animal2 = new Cat();
创建了一个 Cat
类的对象并用 Animal*
类型的指针 animal2
指向它。animal1->makeSound();
时,由于 makeSound
是虚函数,虽然 animal1
是 Animal*
类型的指针,但实际指向的是 Dog
类的对象,所以会动态绑定并调用 Dog
类中重新定义的 makeSound
函数,输出 Woof!
。animal2->makeSound();
时,因为 animal2
实际指向的是 Cat
类的对象,所以会调用 Cat
类中重新定义的 makeSound
函数,输出 Meow!
。Dog* dog = new Dog();
Cat* cat = new Cat();
dog->makeSound();
cat->makeSound();
这就并没有体现c++的多态性。
override
关键字来明确表示是在派生类中重新定义基类的虚函数,这样有助于编译器检查函数签名是否正确,避免因疏忽导致的错误。virtual
关键字再次声明该函数,它都依然是虚函数。也就是说,虚函数的 “虚” 特性是可以继承的。#include
// 基类
class Base {
public:
virtual ~Base() {
std::cout << "Base destructor called." << std::endl;
}
};
// 派生类
class Derived : public Base {
public:
int* data;
Derived() {
data = new int(10);
}
~Derived() {
std::cout << "Derived destructor called." << std::endl;
delete data;
}
};
int main() {
Base* basePtr = new Derived();
// 因为Base的析构函数是虚函数,所以删除时会先调用Derived的析构函数
// 再调用Base的析构函数,确保资源正确释放
delete basePtr;
return 0;
}
编译器会根据指针的类型来决定调用哪个类的析构函数。如果基类 Base
的析构函数不是虚函数,那么不管这个指针实际指向的是哪个派生类对象(在这里实际指向的是 Derived
类对象),编译器都只会调用基类 Base
的析构函数。(最起初的那段动物案例之所以没有写析构函数是因为类中没有动态分配内存等可能引发泄露空间的操作)
= 0
。例如:class Base {
public:
virtual void func() = 0;
};
虚函数中的动态绑定机制:当通过基类指针或引用调用虚函数时,实际上是通过对象的虚指针找到所属类的虚函数表,然后在虚函数表中查找对应的虚函数地址,从而实现根据对象类型动态地调用相应的虚函数。
综上所述,C++ 虚函数是实现多态性的重要工具,掌握其定义、使用规则、与其他函数(如构造函数、析构函数)的关系以及相关概念(如纯虚函数、抽象类)和内部机制(如虚函数表、动态绑定机制)等知识点,对于编写高效、灵活、可扩展的面向对象程序至关重要。
以上就是关于c++实现多态的过程中涉及到的虚函数的相关知识,如有不当还请多多指教。.