MST

星途 面试题库

面试题:C++ 函数重载在复杂类继承体系中的应用技巧

有一个基类Shape,派生出Triangle和Rectangle两个子类。要求在这些类中使用函数重载实现一个draw函数,用于绘制图形(这里简单输出相关信息表示绘制)。在主函数中创建不同子类对象并调用draw函数,展示函数重载在类继承体系中的正确使用方式,同时阐述在这种场景下函数重载可能遇到的问题及解决方法。
23.0万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
#include <iostream>

// 基类Shape
class Shape {
public:
    // 虚函数draw,提供默认实现
    virtual void draw() const {
        std::cout << "Drawing a shape." << std::endl;
    }
};

// 子类Triangle继承自Shape
class Triangle : public Shape {
public:
    // 重写draw函数
    void draw() const override {
        std::cout << "Drawing a triangle." << std::endl;
    }
};

// 子类Rectangle继承自Shape
class Rectangle : public Shape {
public:
    // 重写draw函数
    void draw() const override {
        std::cout << "Drawing a rectangle." << std::endl;
    }
};

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

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

    return 0;
}

函数重载在类继承体系中可能遇到的问题及解决方法

  1. 问题
    • 隐藏问题:在子类中定义与基类同名但参数列表不同的函数时,会隐藏基类中的同名函数。例如,如果Triangle类定义了void draw(int param),那么Triangle对象将无法直接调用基类的void draw()函数,即使在继承体系中看起来应该可以调用。
  2. 解决方法
    • 使用using声明:在子类中使用using声明来引入基类中同名函数,使得在子类作用域中可以访问基类的同名函数。例如,在Triangle类中添加using Shape::draw;,这样Triangle对象就可以调用基类的draw()函数。
    • 合理设计函数签名:确保在子类中定义新的函数时,仔细考虑函数签名,避免不经意地隐藏基类函数。同时,使用override关键字来明确标识重写基类虚函数,这样编译器可以帮助检测函数签名是否正确匹配基类虚函数,减少隐藏问题的发生。