构造多态类

时间:2014-07-16 13:56:40

标签: c++

我对构建使用继承的类的方式有疑问。在下面的示例中,对Base构造函数的调用依赖于Derived类中实现的函数。此函数再次依赖于Derived成员generator,该成员在Base构造函数调用之后才会初始化。

如果首先构造Base类,变量Base::in_不会包含垃圾数据吗?

class Derived
    : public Base
{

    Derived()
        : Base(get_data()),
          generator(5) {}

    Generator generator;

    int get_data() { return generator.get_some_data(); }
};

class Base
{
    Base(int in)
         : in_(in) {}

    int in_;

}

3 个答案:

答案 0 :(得分:2)

首先,代码中没有任何内容是多态的。多态性是关于虚函数的。

接下来,您的 Base完全不依赖。在class Base {和匹配的}之间查看,那里的任何内容都不依赖于任何外部。

BaseDerived 子对象的构造取决于Derived的另一个成员,该成员是在Base之后构建的。您的分析基本上是正确的,这是一个真正的问题,需要通过重构您的课程来解决。

最简单的方法是Base的两阶段初始化(以下是伪代码,可能无法编译):

class Base {
    Base(int in = 0) : in_(in) {}
    void set(int in) { in_ = in; }
    int in_;
};

class Derived : public Base {    
    Derived() : Base(), generator(5) {
      Base::set(generator);
    }
    ...
};

另一种方法是将依赖项移动到另一个基类:

class Base2 { ... generator implemented here ... };
class Derived : public Base2, public Base {
  Derived() : Base2(5), Base(Base2::generator) {}
};

答案 1 :(得分:0)

我不知道标准说的是什么,但这显然是generator调用get_data()时的价值问题,因为如果你从其他地方调用它的话会是这样的构造函数。

从构造函数中调用的代码与其他代码没有任何不同。
我的猜测是在构造生成器之前调用get_data(),因此在运行时会得到一个NULL异常 另一点需要提及的是,基类当然是首先构建的。它是基类。 Derived是一个Base,它有一个字段in_
根据经验,它始终是一个很好的模式:

  1. 避免来自构造函数的方法调用。为此使用额外的init方法。
  2. 在任何情况下都要注意循环构造函数调用。
  3. 您还可以在get_data中对Base进行抽象,然后在Init() Base内调用它,这将是实现对子类的依赖的正确方法正如你所说的那样。

    class Derived
        : public Base
    {
    
        Derived()
            : Base(),
              generator(5) {}
    
        Generator generator;
    
        virtual int get_data() { return generator.get_some_data(); }
    };
    
    class Base
    {
        Base()
        {
    
        }
    
        Init() {
           in_ = get_data();}   
        int in_;
    
        virtual int get_data() = 0;
    }
    

答案 2 :(得分:0)

请参阅Order of calling constructors/destructors in inheritance

在初始化Derived的任何成员之前,将调用Base的构造函数。所以当调用get_data()时,生成器不会被初始化。

基本上,Base将使用垃圾进行初始化。