MST

星途 面试题库

面试题:C++中多态性的实现方式

请详细阐述C++中多态性是如何实现的,包括静态多态和动态多态,并举例说明其在实际编程中的应用场景。
48.9万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

1. 静态多态

  • 实现方式:通过函数重载和模板(函数模板、类模板)来实现。在编译期,编译器根据函数参数的类型、个数或模板参数的不同,确定调用哪个具体的函数版本。
  • 示例 - 函数重载
#include <iostream>

// 函数重载示例
void print(int num) {
    std::cout << "Printing integer: " << num << std::endl;
}

void print(double num) {
    std::cout << "Printing double: " << num << std::endl;
}

int main() {
    print(5);
    print(3.14);
    return 0;
}
  • 示例 - 函数模板
#include <iostream>

// 函数模板示例
template <typename T>
void print(T num) {
    std::cout << "Printing value: " << num << std::endl;
}

int main() {
    print(10);
    print(3.14f);
    print("Hello");
    return 0;
}
  • 应用场景:在编写通用的算法或工具函数时,函数重载可以根据不同的数据类型提供不同的实现,而模板则可以在编译期生成针对不同类型的代码,提高代码复用性。例如标准库中的std::sort函数,它可以对不同类型的容器进行排序,通过模板实现了对各种可比较类型的支持。

2. 动态多态

  • 实现方式:通过虚函数和指针或引用(基类指针或引用指向派生类对象)来实现。在运行期,程序根据对象的实际类型来决定调用哪个虚函数的实现。这依赖于虚函数表(vtable)和虚指针(vptr)机制。每个包含虚函数的类都有一个虚函数表,类的对象含有一个虚指针,指向该虚函数表。当通过基类指针或引用调用虚函数时,程序会根据虚指针找到虚函数表,进而找到对应对象实际类型的虚函数实现。
  • 示例
#include <iostream>

class Shape {
public:
    virtual void draw() {
        std::cout << "Drawing a shape" << std::endl;
    }
};

class Circle : public Shape {
public:
    void draw() override {
        std::cout << "Drawing a circle" << std::endl;
    }
};

class Rectangle : public Shape {
public:
    void draw() override {
        std::cout << "Drawing a rectangle" << std::endl;
    }
};

int main() {
    Shape* shapes[2];
    shapes[0] = new Circle();
    shapes[1] = new Rectangle();

    for (int i = 0; i < 2; ++i) {
        shapes[i]->draw();
    }

    for (int i = 0; i < 2; ++i) {
        delete shapes[i];
    }
    return 0;
}
  • 应用场景:在面向对象编程中,动态多态常用于实现基于继承体系的行为多态。例如在图形绘制系统中,不同的图形类(如圆形、矩形等)继承自一个基类Shape,通过动态多态可以根据实际的图形类型调用相应的draw函数进行绘制。在游戏开发中,不同的角色类(玩家、怪物等)继承自一个基类,通过动态多态可以根据实际的角色类型执行不同的行为,如攻击、移动等。