MST

星途 面试题库

面试题:C++中多态的实现方式有哪些

请详细阐述C++中实现多态的几种方式,并分别举例说明每种方式在实际代码中的应用。
30.5万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

在C++ 中,实现多态主要有以下几种方式:

函数重载(编译时多态)

  • 原理:函数重载是指在同一作用域内,可以有多个同名函数,这些函数的参数列表(参数个数、类型或顺序)不同。编译器会根据调用函数时提供的实参,在编译阶段就确定要调用的具体函数。
  • 示例
#include <iostream>

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

void print(double num) {
    std::cout << "打印双精度浮点数: " << num << std::endl;
}

void print(const char* str) {
    std::cout << "打印字符串: " << str << std::endl;
}

int main() {
    print(10);
    print(3.14);
    print("Hello, World!");
    return 0;
}
  • 实际应用:常用于对不同类型数据执行相似操作的场景,比如在一个数学库中,可能有 add(int a, int b)add(double a, double b) 等函数来实现不同类型数据的加法。

运算符重载(编译时多态)

  • 原理:允许对已有的运算符进行重新定义,以用于自定义数据类型。编译器根据操作数的类型,在编译阶段确定使用哪个重载的运算符函数。
  • 示例
#include <iostream>

class Complex {
public:
    double real;
    double imag;

    Complex(double r = 0, double i = 0) : real(r), imag(i) {}

    // 重载 + 运算符
    Complex operator+(const Complex& other) {
        return Complex(real + other.real, imag + other.imag);
    }

    // 重载 << 运算符用于输出
    friend std::ostream& operator<<(std::ostream& os, const Complex& c) {
        os << "(" << c.real << " + " << c.imag << "i)";
        return os;
    }
};

int main() {
    Complex c1(1, 2);
    Complex c2(3, 4);
    Complex result = c1 + c2;
    std::cout << "结果: " << result << std::endl;
    return 0;
}
  • 实际应用:在自定义数据结构中,使运算符能像对基本数据类型那样自然地使用,比如在矩阵类中重载 + 运算符实现矩阵相加。

虚函数和多态(运行时多态)

  • 原理:通过在基类中定义虚函数(使用 virtual 关键字),在派生类中重写这些虚函数。当通过基类指针或引用调用虚函数时,程序会在运行时根据对象的实际类型来决定调用哪个类的虚函数版本。
  • 示例
#include <iostream>

class Shape {
public:
    virtual void draw() {
        std::cout << "绘制形状" << std::endl;
    }
};

class Circle : public Shape {
public:
    void draw() override {
        std::cout << "绘制圆形" << std::endl;
    }
};

class Rectangle : public Shape {
public:
    void draw() override {
        std::cout << "绘制矩形" << 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();
        delete shapes[i];
    }
    return 0;
}
  • 实际应用:在图形绘制系统中,不同形状类继承自一个基类 Shape,通过基类指针或引用调用 draw 函数可以实现根据实际对象类型绘制不同图形,实现了代码的灵活性和扩展性。

模板(编译时多态)

  • 原理:模板允许编写通用的代码,不依赖于具体的数据类型。编译器会根据实际使用的类型,为每种类型生成一份具体的代码实例。
  • 示例
#include <iostream>

// 模板函数示例
template <typename T>
T add(T a, T b) {
    return a + b;
}

int main() {
    int intResult = add(5, 3);
    double doubleResult = add(2.5, 1.5);
    std::cout << "整数相加结果: " << intResult << std::endl;
    std::cout << "双精度浮点数相加结果: " << doubleResult << std::endl;
    return 0;
}
  • 实际应用:在标准模板库(STL)中广泛应用,如 std::vectorstd::sort 等,使代码可以适用于多种数据类型,提高代码复用性。