- 在主函数中创建指针数组并调用
move
函数实现多态效果
#include <iostream>
// 抽象类 Character
class Character {
public:
// 纯虚函数 move
virtual void move() = 0;
};
// Warrior 派生类
class Warrior : public Character {
public:
void move() override {
std::cout << "Warrior moves with sword slashing." << std::endl;
}
};
// Mage 派生类
class Mage : public Character {
public:
void move() override {
std::cout << "Mage moves with teleportation." << std::endl;
}
};
int main() {
// 创建 Character 指针数组
Character* characters[2];
// 存储不同类型角色对象的指针
characters[0] = new Warrior();
characters[1] = new Mage();
// 通过数组调用 move 函数实现多态
for (int i = 0; i < 2; ++i) {
characters[i]->move();
}
// 释放内存
for (int i = 0; i < 2; ++i) {
delete characters[i];
}
return 0;
}
- 纯虚函数在多态接口设计中的关键作用
- 定义统一接口:纯虚函数在抽象类中定义了一个通用的接口,比如
Character
类中的 move
纯虚函数。所有派生类(如 Warrior
和 Mage
)都必须实现这个接口,这样就确保了不同类型的角色对象都有一个统一的 move
行为接口,方便在代码中以统一的方式调用,实现多态。
- 强制派生类实现特定行为:纯虚函数强制派生类提供自己的实现。这在游戏开发场景中很重要,因为不同角色(
Warrior
和 Mage
)的移动方式应该是不同的,通过纯虚函数,能保证每个派生类都根据自身特性实现 move
函数,从而实现多态的具体表现。
- 可能遇到的内存管理问题及解决方案
- 内存泄漏问题:在上述代码中,如果忘记释放
characters
数组中指针所指向的对象(即没有 delete characters[i];
这一步),就会导致内存泄漏。因为 new
分配的内存如果不手动 delete
,程序结束时这块内存不会被自动回收。
- 解决方案:
- 手动释放内存:如代码中所示,在使用完
characters
数组中的指针后,通过 for
循环逐个调用 delete
来释放每个指针指向的对象,确保内存被正确回收。
- 使用智能指针:可以使用
std::unique_ptr
或 std::shared_ptr
来管理动态分配的对象。例如,将 Character* characters[2];
改为 std::unique_ptr<Character> characters[2];
,然后在创建对象时使用 std::make_unique
,这样智能指针会在其作用域结束时自动释放所管理的对象,有效避免内存泄漏。修改后的代码如下:
#include <iostream>
#include <memory>
class Character {
public:
virtual void move() = 0;
};
class Warrior : public Character {
public:
void move() override {
std::cout << "Warrior moves with sword slashing." << std::endl;
}
};
class Mage : public Character {
public:
void move() override {
std::cout << "Mage moves with teleportation." << std::endl;
}
};
int main() {
std::unique_ptr<Character> characters[2];
characters[0] = std::make_unique<Warrior>();
characters[1] = std::make_unique<Mage>();
for (int i = 0; i < 2; ++i) {
characters[i]->move();
}
// 无需手动 delete,智能指针会自动释放内存
return 0;
}