MST

星途 面试题库

面试题:C++初始化成员列表在多态与复杂对象构造中的运用

给定一个抽象基类`Shape`,包含纯虚函数`draw`。有两个派生类`Circle`和`Rectangle`,`Circle`类有成员变量`radius`(`double`类型),`Rectangle`类有成员变量`width`和`height`(均为`double`类型)。现在有一个容器`std::vector<Shape*>`,需要向其中添加`Circle`和`Rectangle`的对象指针。请使用初始化成员列表正确构造`Circle`和`Rectangle`对象,并展示如何将它们添加到容器中。另外,解释在构造这些复杂对象时,初始化成员列表对于对象构造顺序和多态性的影响。
11.2万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
#include <iostream>
#include <vector>

// 抽象基类Shape
class Shape {
public:
    virtual void draw() const = 0;
    virtual ~Shape() = default;
};

// Circle类
class Circle : public Shape {
public:
    double radius;
    Circle(double r) : radius(r) {}

    void draw() const override {
        std::cout << "Drawing a circle with radius " << radius << std::endl;
    }
};

// Rectangle类
class Rectangle : public Shape {
public:
    double width;
    double height;
    Rectangle(double w, double h) : width(w), height(h) {}

    void draw() const override {
        std::cout << "Drawing a rectangle with width " << width << " and height " << height << std::endl;
    }
};

int main() {
    std::vector<Shape*> shapes;

    // 添加Circle对象指针到容器
    shapes.push_back(new Circle(5.0));
    // 添加Rectangle对象指针到容器
    shapes.push_back(new Rectangle(4.0, 6.0));

    // 多态调用draw函数
    for (const auto& shape : shapes) {
        shape->draw();
        delete shape;
    }

    return 0;
}

初始化成员列表对于对象构造顺序和多态性的影响

  1. 对象构造顺序
    • 使用初始化成员列表时,成员变量按照它们在类定义中声明的顺序进行初始化,而不是按照初始化成员列表中出现的顺序。例如,在Circle类中,radius在类定义中声明,初始化成员列表Circle(double r) : radius(r) {}会按照声明顺序初始化radius。这确保了成员变量初始化的一致性和可预测性。如果不使用初始化成员列表,而是在构造函数体中赋值,会先默认初始化成员变量,然后再赋值,这样会增加不必要的开销。
  2. 对多态性的影响
    • 初始化成员列表对于多态性没有直接影响。多态性主要依赖于虚函数和指针或引用。在上述代码中,通过std::vector<Shape*>存储CircleRectangle的指针,在调用draw函数时,会根据实际对象的类型(CircleRectangle)来调用相应的draw实现,这就是多态性的体现。初始化成员列表主要是用于对象成员变量的初始化,确保对象在构造时处于正确的状态,以便后续多态调用等操作能够正常进行。