卡码笔记
首页
计算机基础
C++
Java
面经
笔记广场 (opens new window)
代码随想录 (opens new window)
首页
计算机基础
C++
Java
面经
笔记广场 (opens new window)
代码随想录 (opens new window)
  • 基础与语法

  • 面向对象

    • C++构造函数有几种,分别什么作用?
    • 什么是构造函数和析构函数?构造函数和析构函数可以是虚函数吗?为什么?
    • C++的重载和重写,以及它们的区别和实现方式
    • C++怎么实现多态
      • 简要回答
      • 详细回答
      • 代码示意
      • 知识拓展
    • C++中的虚函数和纯虚函数有什么区别?
    • 虚函数怎么实现的?
    • 虚函数表是什么
    • 多重继承的优缺点及菱形继承问题
    • 如何禁止一个类被继承
    • 深拷贝和浅拷贝的区别?
    • this指针的原理
    • C++如何实现一个单例模式?
  • STL 与容器

  • 内存管理

  • C++11 与现代 C++

  • 智能指针

  • 并发与 I/O

# C++怎么实现多态

# 简要回答

C++通过虚函数(virtual function)和继承实现多态。基类中声明虚函数,派生类可以重写(override)这些函数。

通过基类指针或引用调用虚函数时,会根据实际对象类型调用相应的函数实现。

# 详细回答

C++多态分为编译时多态和运行时多态:

编译时多态:通过函数重载和模板实现

运行时多态:通过虚函数和继承实现

虚函数表(vtable):每个包含虚函数的类都有一个虚函数表,存储虚函数地址

虚指针(vptr):每个对象包含一个指向其类虚函数表的指针

动态绑定:通过vptr在运行时确定调用哪个函数实现

总结: C++ 多态 = virtual + 继承 + 基类指针/引用调用 + 重写

# 代码示意

#include <iostream>
using namespace std;

// 基类:动物
class Animal {
public:
    virtual void say() {  // 加virtual才能被重写
        cout << "我是动物" << endl;
    }
    virtual ~Animal() {}  // 记得写虚析构
};

// 派生类:狗
class Dog : public Animal {
public:
    void say() override {  // override明确表示重写
        cout << "汪汪汪" << endl;
    }
};

// 派生类:猫
class Cat : public Animal {
public:
    void say() override {
        cout << "喵喵喵" << endl;
    }
};

int main() {
    Animal* myPets[2];
    myPets[0] = new Dog();  // 狗对象
    myPets[1] = new Cat();  // 猫对象

    // 同样的调用,不同表现
    for (int i = 0; i < 2; ++i) {
        myPets[i]->say();
        delete myPets[i];
    }

    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

# 知识拓展

  • 知识图解 image

多态调用过程示例:

Animal* animal = new Dog();

animal->speak();

(1)通过animal指针找到Dog对象

(2)通过对象的vptr找到Dog类的虚函数表

(3)在虚表中查找speak()的地址

(4)跳转到Dog::speak()执行

  • 拓展 抽象类:用 =0 表示必须重写,比如virtual void run()=0,使类成为抽象类

c++11新特性涉及override和final两个,其中override明确表示要重写,final表示禁止子类重写

性能方面:虚函数调用比普通函数稍慢一些

  • 面试官可能追问

多态的底层是咋实现的?

答: 每个带virtual的类,编译器会悄悄搞一张表,叫虚函数表(vtable),里面列着所有虚函数的地址。

然后每个对象里,会藏一个指针,指着这张表(这个指针叫 vptr)。

调用虚函数时,其实是通过 vptr 去 vtable 里找对应的函数地址,然后跳转执行,这叫动态绑定。

Last Updated: 3/10/2026, 6:08:48 PM

← C++的重载和重写,以及它们的区别和实现方式 C++中的虚函数和纯虚函数有什么区别? →

评论

验证登录状态...

侧边栏
夜间
卡码简历
代码随想录
卡码投递表🔥
2026群
添加客服微信 PS:通过微信后,请发送姓名-学校-年级-2026实习/校招
支持卡码笔记
鼓励/支持/赞赏Carl
1. 如果感觉本站对你很有帮助,也可以请Carl喝杯奶茶,金额大小不重要,心意已经收下
2. 希望大家都能梦想成真,有好的前程,加油💪