【问题标题】:How to allocate array in base constructor with size based on derived class?如何在基于派生类的大小的基构造函数中分配数组?
【发布时间】:2010-10-16 00:22:59
【问题描述】:

我有一个类的层次结构。基类使用一些可从文件加载(并在运行时可重新加载)的调整参数。每个派生类都可以添加一些额外的参数。我正在寻找一种在基本构造函数中分配正确大小的参数数组的方法,这样我就不必在派生类中重新分配和重新分配。我希望有这样的东西,但它不起作用(参数总是有 2 个元素):

   class Base
   { static int nParms;
     virtual int getNParms() { return nParms;}
     float *parameters;
   public:
     Base() 
     { parameters= new float[this->getNParms()];
       parameters[0] = globalReloadableX;
       parameters[1] = globalReloadableY;
     }
   };
   int Base::nParams =2;

   class Derived : public Base
   { static int nParms;
     virtual int getNParms() { return nParms;}
   public:
     Derived() : Base()
     { parameters[2] = globalReloadableZ;
     }
   }
   int Derived::nParams =3;

我见过this question,但那里的解决方案对我来说不太奏效。 我还尝试在每个类中将参数设为常规数组:

  class Base
  {  float parameters[2]
    ...
  class Derived : public Base
  {  float parameters[3]
    ...

但这使得 Derived 有 2 个单独的数组。

有什么想法吗?

【问题讨论】:

    标签: c++ inheritance static constructor


    【解决方案1】:

    为什么不在基类的构造函数中传递所需的数组大小作为参数?

    (虚函数不调用派生类的原因是因为C++虚函数就是这样工作的;从概念上讲,在派生类构造函数完成之前,对象的类型仍然是基类。)

    【讨论】:

    • 为什么不呢?太明显了!有时我只是太专注于细节......感谢您解释原因。
    • 没问题,每个人都会遇到!
    【解决方案2】:

    将大小作为参数怎么样?

    class Base
    { static int nParms;
      virtual int getNParms() { return nParms;}
      float *parameters;
    public:
      Base(int n = nParams) 
      { parameters= new float[n];
        parameters[0] = globalRelodableX;
        parameters[1] = globalRelodableY;
      }
    };
    int Base::nParams =2;
    
    class Derived : public Base
    { static int nParms;
      virtual int getNParms() { return nParms;}
    public:
      Derived() : Base(nParams)
      { parameters[2] = globalRelodableZ;
      }
    }
    int Derived::nParams =3;
    

    【讨论】:

      【解决方案3】:

      为什么要使用数组? std::vector 将允许您在派生类中使用尽可能多的参数,而基类不知道(或关心)它需要多少。

      【讨论】:

      • 这很好。我实际上在其他地方使用向量。但我仍然在 C 中完成大部分工作,所以当我添加功能时,我倾向于使用我所知道的......
      【解决方案4】:

      我会考虑使用 std::map。它可以随基数和派生数一起增长,而不关心其他使用的参数数量。键/值对可能更容易管理数字索引,尽管这显然取决于应用程序。

      【讨论】:

        【解决方案5】:

        我喜欢 Earwicker 和 Steve 的答案,具体取决于要求。如果频繁地创建和销毁这些对象中的许多,那么您需要尽可能少的内存分配,因此 Earwicker 的更胜一筹。但是,如果这是通常“创建并且很少重新制作”的东西,那么我会选择史蒂夫的答案,因为地图通常更容易使用,并且可以根据需要动态增长,但如果这个对象经常被制造和破坏。

        【讨论】:

          【解决方案6】:

          您可以按照其他人的建议将其作为构造函数的参数,但您也可以将 Base 设为模板类,并将大小作为参数。这有很多优点,比如不需要在堆上分配数组:

          template <size_t nParams>
          class Base
          {
              float parameters[nParams];
          public:
              Base()
              { // could use a static_assert(nParams > 1) here...
                parameters[0] = globalRelodableX;
                parameters[1] = globalRelodableY;
              }
          };
          
          class Derived : public Base<3>  // or whatever
          {
          public:
              Derived()
              { parameters[2] = globalRelodableZ; }
          };
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2016-12-20
            • 2018-07-16
            • 2016-07-19
            • 2018-07-21
            • 2012-12-24
            • 2014-03-26
            • 1970-01-01
            相关资源
            最近更新 更多