MST

星途 面试题库

面试题:C++类实例化中的模板与多态结合

编写一个模板类`Container`,它可以容纳不同类型的对象。要求`Container`类中的元素支持多态行为。例如,假设有一个基类`Shape`,以及派生类`Rectangle`和`Circle`继承自`Shape`。实例化`Container`对象时,能够添加不同派生类的`Shape`对象,并通过多态方式调用它们各自的`draw`函数。请详细说明实现过程中涉及到的C++特性,如模板实例化、动态绑定等是如何协同工作的。
37.7万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. 定义基类和派生类

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

    在这个部分,我们定义了Shape基类,它有一个虚函数drawRectangleCircle类继承自Shape,并重写了draw函数。这体现了C++的继承和多态特性。虚函数draw使得在运行时能够根据对象的实际类型来调用正确的draw函数,即动态绑定。

  2. 定义Container模板类

    #include <vector>
    #include <memory>
    
    template<typename T>
    class Container {
    private:
        std::vector<std::unique_ptr<T>> elements;
    public:
        void addElement(std::unique_ptr<T> element) {
            elements.push_back(std::move(element));
        }
    
        void drawAll() const {
            for (const auto& element : elements) {
                element->draw();
            }
        }
    };
    
    • 模板实例化Container是一个模板类,模板参数T表示容纳对象的类型。当我们实例化Container<Shape>时,编译器会根据模板定义生成对应的Container类,这就是模板实例化的过程。
    • 动态绑定Container类中使用了std::unique_ptr<T>来存储对象指针。当drawAll函数调用element->draw()时,由于draw是虚函数,C++的运行时系统会根据element所指向对象的实际类型(RectangleCircle)来调用正确的draw函数,实现动态绑定。
    • 智能指针:使用std::unique_ptr来管理对象的生命周期,避免了手动内存管理的复杂性和内存泄漏问题。addElement函数通过std::move将传入的std::unique_ptr所有权转移到elements向量中。
  3. 测试代码

    int main() {
        Container<Shape> container;
        container.addElement(std::make_unique<Rectangle>());
        container.addElement(std::make_unique<Circle>());
        container.drawAll();
        return 0;
    }
    

    main函数中,我们实例化了Container<Shape>对象,并向其中添加了RectangleCircle对象。然后调用drawAll函数,它会以多态的方式调用每个对象的draw函数,输出:

    Drawing a rectangle
    Drawing a circle
    

综上所述,通过模板实例化,我们可以创建容纳不同类型对象的Container类。通过虚函数和指针(这里是智能指针),实现了多态行为中的动态绑定,使得Container类能够以统一的方式处理不同派生类的对象,并调用它们各自的函数。