【问题标题】:Construction calling order (C++)构造调用顺序 (C++)
【发布时间】:2012-02-21 19:58:26
【问题描述】:

我有两个继承自同一个抽象超类的子类。所有子类都有一个共同的操作,这取决于几个属性。让我用一个例子来解释:

说这是超类 A(A 是抽象的):

class superClass
{
  int valueA;
  int valueB;
  float* array;

   public superClass(){
      array[valueA + valueB]
   }

   virtual foo(){
   }

}

这些是我的子类:

class firstSubClass: superClass
{

   public firstSubClass():superClass(), valueA(100),valueB(2){
   }

   foo(){
   }

}

class secondSubClass: superClass
{

   public secondSubClass():superClass(), valueA(50),valueB(3){
   }

   foo(){
   }

}

数组会被正确初始化吗?这意味着,是在超类之前调用​​子类构造函数,还是相反?

有没有办法通过将初始化行为放入超类中来使两个子类共有的初始化行为?

提前致谢。

【问题讨论】:

    标签: c++ inheritance


    【解决方案1】:

    首先调用superClass 构造函数。

    superClass 构造函数应该负责初始化superClass's 数据成员 而firstSubClass应该初始化自己的数据成员并调用superClass's构造函数;

    有关构造函数调用顺序的更多信息here,您可能还想了解构造函数初始化列表here

    所以,我将 superClassfirstSubClasssecondSubClass 定义为:

    class superClass
    {
      int valueA;
      int valueB;
      float* array;
    
      public:
    
       superClass( int a , int b ): valueA(a),valueB(b) {
    
          array = new float[valueA + valueB];
       }
       virtual foo(){
       }
    
    }
    
    
    
    class firstSubClass: public superClass
    {
    
       public:
    
       firstSubClass():superClass(100,2){ //calls superclass's constructor
       }
    
       foo(){
       }
    
    }
    
    class secondSubClass: public superClass
    {
    
       public :
    
       secondSubClass():superClass(50 , 3){
       }
    
       foo(){
       }
    
    }
    

    【讨论】:

    • 这很有意义。我认为这是您为自己没有弄清楚而感到尴尬的情况之一。谢谢!
    • @kelmer ,很高兴为您提供帮助。如果您喜欢上面的帖子,请将其标记为答案:P。
    【解决方案2】:

    如果我理解得很好,您希望超类在构建任何子类时创建(而不仅仅是初始化)一个浮点数组。创建继承类的实例时,首先调用基类构造函数,您需要将 valueA 和 valueB 值传递给它 - 您需要将它们添加为构造函数参数:

    superClass::superClass(int valueA, int valueB) : 
       valueA(valueA), valueB(valueB), array(0)
    {
       // now create an array of requested length - allocate memory for it
       array = new float[valueA + valueB];
    }
    
    // don't forget to deallocate memory for it (possibly in destructor)
    superClass::~superClass()
    {
       delete[] array;
       array = 0;
    }
    

    那么,当你创建继承类的实例时,你可以提供 valueA 和 valueB 作为超类构造函数的参数:

    firstSubClass::firstSubClass() : superClass(100, 2)
    {
       //...
    }
    

    使用硬编码值(幻数)不是一个好习惯,因此最好将 valueA 和 valueB 添加为子类构造函数参数:

    firstSubClass::firstSubClass(int valueA, int valueB) : superClass(valueA, valueB)
    {
       //...
    }
    

    最后,您应该避免使用数组。这是C++,使用std::vector<float>,更安全,更容易使用!

    【讨论】:

    • @kelmer - 向量只是数组的包装器,它们使您的事情变得更容易,但不太可能降低效率。
    • @kelmer 与容易出错且难以维护数组的高级别的可能错误相比,性能差异是不存在的。
    • 谢谢大家,我会听从你的建议的:)
    • @kelmer 看看这个问题 - 它会给你一些关于这个问题的提示:stackoverflow.com/questions/381621/…
    猜你喜欢
    • 1970-01-01
    • 2012-08-22
    • 2014-01-28
    • 1970-01-01
    • 1970-01-01
    • 2010-12-25
    • 2017-12-07
    • 2012-02-28
    • 2010-10-13
    相关资源
    最近更新 更多