C++中多态-面试回答

谈谈你了解的多态

多态就是:同样的调用语句有不同的表现形态。即一般根据基类指针指向的实际对象,调用相应的同名函数。

多态的条件

  • 1.必须有继承
  • 2.基类中必须用virtual关键字声明函数,即重写虚函数
  • 3.用基类指针指向对象

虚函数相关

基类中,在函数名前用virtual关键字声明,在派生类中再次实现同名函数(函数参数类型、个数,返回值类型必须一样)。

在编译时,编译器遇到virtual关键字会在常量区创建一个虚函数表(存的是相应函数的指针),每一个类都有一个虚函数表,每一个对象都有一个指向虚函数表的指针vptr。在用基类指针调用虚函数时,vptr会指向相应虚函数表,通过寻址调用相应的虚函数。

### 回答问题: **C++ 多态(Polymorphism)** 是面向对象编程的三大核心特性之一(另外两个是封装和继承),它允许一个接口(函数或对象)有多种不同的实现方式。通俗地说,就是“一个接口,多种实现”。 在 C++ 中,多态主要通过 **虚函数(virtual functions)** 来实现。 --- ### 一、多态的分类 | 类型 | 说明 | |------|------| | 编译时多态(静态绑定) | 函数重载、运算符重载,编译器在编译时决定调用哪个函数 | | 运行时多态(动态绑定) | 通过虚函数机制,在运行时决定调用哪个函数 | --- ### 二、运行时多态的实现:虚函数 #### 1. 虚函数(Virtual Function) - 在基类中声明为 `virtual` 的函数,可以在派生类中被重写。 - 基类的虚函数可以有实现,也可以是纯虚函数。 #### 示例: ```cpp #include <iostream> using namespace std; class Animal { public: virtual void speak() const { cout << "Animal speaks" << endl; } }; class Dog : public Animal { public: void speak() const override { cout << "Woof!" << endl; } }; class Cat : public Animal { public: void speak() const override { cout << "Meow!" << endl; } }; int main() { Animal* a1 = new Dog(); Animal* a2 = new Cat(); a1->speak(); // 输出: Woof! a2->speak(); // 输出: Meow! delete a1; delete a2; return 0; } ``` 在这个例子中: - `Animal` 是基类,`Dog` 和 `Cat` 是派生类。 - 通过基类指针调用虚函数 `speak()`,会根据对象的实际类型调用相应的实现。 #### 2. 虚析构函数(Virtual Destructor) - 如果一个类可能被继承,那么它的析构函数必须是 `virtual`。 - 否则,通过基类指针删除派生类对象时,会导致**未定义行为**(派生类部分不会被析构)。 ```cpp class Base { public: virtual ~Base() {} // 虚析构函数 }; class Derived : public Base { public: ~Derived() { // 做清理工作 } }; ``` #### 3. 纯虚函数(Pure Virtual Function) - 没有实现的虚函数,格式为 `virtual void func() = 0;` - 包含纯虚函数的类是抽象类(abstract class),不能实例化。 ```cpp class Shape { public: virtual void draw() const = 0; // 纯虚函数 virtual ~Shape() {} }; class Circle : public Shape { public: void draw() const override { cout << "Drawing a circle" << endl; } }; ``` --- ### 三、多态的底层机制:虚函数表(vtable)与虚函数指针(vptr) - 每个有虚函数的类都有一个**虚函数表(vtable)**,它是一个函数指针数组,保存虚函数的地址。 - 每个对象有一个隐藏的指针(**vptr**),指向其所属类的虚函数表。 - 当调用虚函数时,程序通过 vptr 找到对应的虚函数表,再根据函数在表中的位置调用正确的函数。 --- ### 四、多态的使用场景 1. **接口编程**:定义统一接口,不同实现。 2. **容器存储不同子类对象**:如 `vector<Animal*>` 存储 `Dog`, `Cat` 等。 3. **回调机制**:通过多态实现灵活的回调函数。 4. **插件系统**:通过接口加载不同插件实现。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值