面试题答案
一键面试-
定义基类和派生类:
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
基类,它有一个虚函数draw
。Rectangle
和Circle
类继承自Shape
,并重写了draw
函数。这体现了C++的继承和多态特性。虚函数draw
使得在运行时能够根据对象的实际类型来调用正确的draw
函数,即动态绑定。 -
定义
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
所指向对象的实际类型(Rectangle
或Circle
)来调用正确的draw
函数,实现动态绑定。 - 智能指针:使用
std::unique_ptr
来管理对象的生命周期,避免了手动内存管理的复杂性和内存泄漏问题。addElement
函数通过std::move
将传入的std::unique_ptr
所有权转移到elements
向量中。
- 模板实例化:
-
测试代码:
int main() { Container<Shape> container; container.addElement(std::make_unique<Rectangle>()); container.addElement(std::make_unique<Circle>()); container.drawAll(); return 0; }
在
main
函数中,我们实例化了Container<Shape>
对象,并向其中添加了Rectangle
和Circle
对象。然后调用drawAll
函数,它会以多态的方式调用每个对象的draw
函数,输出:Drawing a rectangle Drawing a circle
综上所述,通过模板实例化,我们可以创建容纳不同类型对象的Container
类。通过虚函数和指针(这里是智能指针),实现了多态行为中的动态绑定,使得Container
类能够以统一的方式处理不同派生类的对象,并调用它们各自的函数。