#include <iostream>
class Base {
public:
virtual void print() {
std::cout << "This is Base::print()" << std::endl;
}
// 析构函数声明为虚函数,确保释放派生类对象时调用正确的析构函数
virtual ~Base() {}
};
class Derived : public Base {
public:
void print() override {
std::cout << "This is Derived::print()" << std::endl;
}
};
int main() {
// 创建一个Derived对象,并使用Base*指针指向它
Base* derivedPtr = new Derived();
derivedPtr->print(); // 调用Derived::print(),实现多态
// 动态分配一个Base数组,其中包含Derived对象和Base对象
Base** baseArray = new Base*[2];
baseArray[0] = new Derived();
baseArray[1] = new Base();
// 遍历数组并调用print函数,实现多态
for (int i = 0; i < 2; ++i) {
baseArray[i]->print();
}
// 释放内存,避免内存泄漏
for (int i = 0; i < 2; ++i) {
delete baseArray[i];
}
delete[] baseArray;
delete derivedPtr;
return 0;
}
指针在实现多态方面的关键作用
- 基类指针指向派生类对象:通过
Base* derivedPtr = new Derived();
这样的语句,基类指针可以指向派生类对象。在调用虚函数 print()
时,根据对象的实际类型(运行时类型)决定调用哪个类的 print
函数,这就是多态的体现。例如 derivedPtr->print();
实际调用的是 Derived::print()
。
- 数组中的多态:在
Base** baseArray
数组中,存放了 Derived
对象和 Base
对象的指针,通过遍历数组调用 print()
函数,同样可以根据对象的实际类型调用对应的 print
函数,实现多态。
内存管理方面的注意事项
- 虚析构函数:在
Base
类中,析构函数必须声明为虚函数。这样当通过 Base*
指针删除派生类对象时(如 delete baseArray[i];
),会调用正确的析构函数,避免内存泄漏。如果析构函数不是虚函数,通过 Base*
指针删除派生类对象时,只会调用 Base
类的析构函数,而不会调用 Derived
类的析构函数,导致派生类中分配的资源无法释放。
- 正确释放内存:对于动态分配的对象(如
new Derived()
和 new Base()
),要使用 delete
来释放内存;对于动态分配的数组(如 new Base*[2]
),要使用 delete[]
来释放内存,以确保所有分配的内存都被正确释放,避免内存泄漏。