如何在基础构造函数中分配基于派生类的大小的数组?

时间:2009-03-27 18:44:10

标签: c++ inheritance static constructor

我有一个类的层次结构。基类使用一些可从文件加载的调整参数(并在运行时可重新加载)。每个派生类可以添加一些额外的参数。我正在寻找一种方法在基础构造函数中分配一个正确大小的参数数组,这样我就不必在派生类中释放和重新分配。我希望这样的东西,但它不起作用(参数总是有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有两个独立的阵列。

有什么想法吗?

6 个答案:

答案 0 :(得分:5)

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

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

答案 1 :(得分: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;

答案 2 :(得分:2)

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

答案 3 :(得分:2)

您可以将其作为构造函数的参数,如其他人所建议的那样,但您也可以将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; }
};

答案 4 :(得分:0)

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

答案 5 :(得分:0)

我喜欢Earwicker和Steve的答案,具体取决于所需要的。如果经常创建和销毁许多这些对象,那么您希望尽可能少地分配内存,因此Earwicker是优越的。然而,如果这通常是“创建并且很少重新制作”,那么我会选择史蒂夫的答案,因为地图通常更容易使用,并且根据需要动态增长,但如果是开销可能太多,如果这个对象正在制造和销毁很多东西。