侧边栏壁纸
博主头像
colo

欲买桂花同载酒

  • 累计撰写 1823 篇文章
  • 累计收到 0 条评论

理解C++中的多态行为

2025-12-12 / 0 评论 / 3 阅读

题目

理解C++中的多态行为

信息

  • 类型:问答
  • 难度:⭐

考点

虚函数,继承,多态原理

快速回答

当基类指针指向派生类对象时:

  • 若函数声明为虚函数(virtual),调用时执行派生类的实现(动态绑定)
  • 若函数未声明为虚函数,调用时执行基类的实现(静态绑定)

代码示例中:

  • speak()是虚函数:输出"Meow!"
  • eat()非虚函数:输出"Animal eats"
## 解析

原理说明

C++多态通过虚函数机制实现:

  • 虚函数:使用virtual关键字声明,运行时根据对象类型决定调用哪个函数
  • 虚函数表(vtable):每个含虚函数的类拥有一个vtable,存储函数指针
  • 动态绑定:通过基类指针/引用调用虚函数时,在运行时查找vtable确定实际调用的函数

代码示例

#include <iostream>
using namespace std;

class Animal {
public:
    virtual void speak() { cout << "Animal sound" << endl; }
    void eat() { cout << "Animal eats" << endl; }
};

class Cat : public Animal {
public:
    void speak() override { cout << "Meow!" << endl; }  // 重写虚函数
    void eat() { cout << "Cat eats fish" << endl; }     // 隐藏基类函数
};

int main() {
    Animal* animal = new Cat();
    animal->speak();  // 输出: Meow! (多态)
    animal->eat();    // 输出: Animal eats (非多态)
    delete animal;
    return 0;
}

关键行为分析

  • speak()调用:虚函数,实际调用Cat::speak()(动态绑定)
  • eat()调用:非虚函数,根据指针类型调用Animal::eat()(静态绑定)

常见错误

  • 忘记将基类函数声明为virtual,导致无法实现多态
  • 派生类函数签名不一致(如const修饰不同),导致意外创建新函数而非重写
  • 未将基类析构函数声明为虚函数,导致派生类资源泄漏

最佳实践

  • 对需要多态的函数始终使用virtual关键字
  • C++11+中使用override关键字明确表示重写(编译器会检查签名)
  • 基类析构函数必须声明为虚函数(virtual ~Animal() = default;

扩展知识

  • final关键字:禁止派生类重写虚函数(virtual void speak() final {...}
  • 纯虚函数virtual void speak() = 0; 使类成为抽象基类
  • 动态类型识别dynamic_cast<Cat*>(animal)可在运行时检查类型