MST

星途 面试题库

面试题:C++纯虚函数在多态接口设计中的深入应用

在C++中,当一个类包含纯虚函数时,它成为抽象类。现在有一个游戏开发场景,存在一个抽象类 `Character`,它有纯虚函数 `move`。`Character` 有两个派生类 `Warrior` 和 `Mage`,分别实现了不同的 `move` 方式。请详细描述在主函数中如何创建一个 `Character` 指针数组,存储不同类型角色对象的指针,并通过该数组调用 `move` 函数实现多态效果,同时说明纯虚函数在这种多态接口设计中的关键作用以及可能遇到的内存管理问题及解决方案。
48.1万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. 在主函数中创建指针数组并调用 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;
}
  1. 纯虚函数在多态接口设计中的关键作用
    • 定义统一接口:纯虚函数在抽象类中定义了一个通用的接口,比如 Character 类中的 move 纯虚函数。所有派生类(如 WarriorMage)都必须实现这个接口,这样就确保了不同类型的角色对象都有一个统一的 move 行为接口,方便在代码中以统一的方式调用,实现多态。
    • 强制派生类实现特定行为:纯虚函数强制派生类提供自己的实现。这在游戏开发场景中很重要,因为不同角色(WarriorMage)的移动方式应该是不同的,通过纯虚函数,能保证每个派生类都根据自身特性实现 move 函数,从而实现多态的具体表现。
  2. 可能遇到的内存管理问题及解决方案
    • 内存泄漏问题:在上述代码中,如果忘记释放 characters 数组中指针所指向的对象(即没有 delete characters[i]; 这一步),就会导致内存泄漏。因为 new 分配的内存如果不手动 delete,程序结束时这块内存不会被自动回收。
    • 解决方案
      • 手动释放内存:如代码中所示,在使用完 characters 数组中的指针后,通过 for 循环逐个调用 delete 来释放每个指针指向的对象,确保内存被正确回收。
      • 使用智能指针:可以使用 std::unique_ptrstd::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;
}