绕过基类构造函数初始化,一个坏习惯?

时间:2014-06-09 15:31:40

标签: c++ opengl inheritance constructor

我在OpenGL项目中有一个基类,它通常代表3DModel。现在我想创建一个更加专业化的类,它将继承自3DModel。我的问题是初始化列表中的强制基类构造函数调用。在我在派生构造函数中完成某些计算之前,是否有正确的方法来延迟此调用?

以下是代码的重要部分:

class 3DModel {
public:
    3DModel(std::vector<...> vertices){ ... };
    [...]
private:
    std::vector<...> vertices;
    [...]
};

class Cylinder : public 3DModel {
public:
    Cylinder(float top_bottom_ratio, float base_diameter);
    [...]
};

//.cpp

Cylinder(float top_bottom_ratio, float base_width)
:3DModel(...) //<---- Mandatory
{
    //I would like to calculate the cylinder vertices here
    //and then feed them to the 3DModel constructor
}

现在,我正在考虑创建一个虚拟3DModel()构造函数,然后调用派生构造函数中的方法来修改基类的属性。但这听起来很奇怪,它会在构造函数中创建一个危险区域,对象将在一段时间内无效。

另一个解决方案是颠倒这个类,只需在主程序中进行计算并使用3DModel构造函数。但这是一个悲伤的解决方案,并破坏了黑盒方法。

你有什么见解吗?

2 个答案:

答案 0 :(得分:2)

您可以将计算放入辅助函数中。理想情况下,将其设置为静态,因此您不会意外地访问unititialized基类值。

class Cylinder : public 3DModel {
public:
    Cylinder(float top_bottom_ratio, float base_diameter);
    [...]
private:
    static calculateVertices(std::vector<...> vertices);
};

//.cpp

Cylinder(float top_bottom_ration, float base_width)
:3DModel(calculateVertices(top_bottom_ratio, base_width))
{
}

std::vector<...> Cylinder::calculateVertices(float top_bottom_ratio, float base_width) {
    // calculate and return vertices here
}

您还可以选择合成而不是继承,其中Cylindar 3DModel而不是 3DModel。 (它可能需要 其他东西,例如Renderable方法{。}}。

答案 1 :(得分:1)

这是base-subclass vs composite的经典问题的一个例子。虽然答案确实以“基类 - 子类”的形式给出了一个例子,但你真的不得不问这是否只是一个包含'3DModel'类的类'Cylinder'。除非您的Cylinder子类(以及任何其他子类)确实为3DModel类添加了更多功能,否则您应该将Cylinder作为3DModel类的组合。