C ++:如何调用具有多个参数的基类构造函数?

时间:2013-03-29 23:08:48

标签: c++ oop constructor derived-class

class BaseClass {
public:
  BaseClass(const byte *buff, long size) { 
     // Some Computation
  }
};

class DerivedClass: public BaseClass {
public:
  std::vector<byte> filebuff;
  long buff_size;
  DerivedClass(): BaseClass(/*How should I send stuff here?*/) 
  { 
  }
  /*return type??*/  cal_func(){
   // Some computation involving file descriptors.
   // Store result in filebuff. Store size of filebuff in buff_size.
    return /*what??*/;
  }
}

我只能想到以下解决方案:

 DerivedClass(): BaseClass(&filebuff[0], cal_func) 

在上面的例子中,我将使函数func()返回filebuff的长度。我依赖于filebuff只是一个地址这一事实,因此编译器是否先将func的计算值放在堆栈上或第一个arg,filebuff无关紧要。

请告诉我这是否是正确的方法。如果第一个参数不是一个地址和一些其他需要在函数func中执行计算的计算值,那么最好的方法是什么呢?

2 个答案:

答案 0 :(得分:2)

看起来您正在尝试将其他人编写的类(例如,在不同的库中)包含两个参数,而另一个类(您编写的)具有更清晰的界面。我是对的吗?

您提出的解决方案是从其他基类派生,然后使用派生类来存储放在基类中的参数。上面的方法的问题是,当你调用基类构造函数时,派生类还没有完全构造(即filebuff和bufsize不能保证已经初始化为任何东西)。

我建议采用另一种方法,而不是派生,你有一个包含基类的WrapperClass,以及你拥有的两个数据成员,如下所示:

class Wrapper {
public:
  Base base;
  std::vector<byte> filebuff;
  long buff_size;
  Wrapper();
}

因此,在包装类的构造函数中,您可以执行以下操作:

WrapperClass::WrapperClass() {
  //do whatever you want to initialize filebuff and buffsize here
  calcfunc();

  //now pass them in to your base class
  base = Base(filebuff, buffsize);
}

[编辑]

替代

上面的解决方案假设您的基类有一个默认构造函数,即Base()。它可能不是,你不能创建一个。如果是这样,那么上面的代码将无法编译,因为无法默认初始化base成员变量。另一种方法是使用指向Base类的指针,例如Base*std::unique_ptr<Base>,或者直接使用某种此类机制而不是Base成员。这样,您可以准确控制Base类初始化的时间。所以:

//class definition
class Wrapper {
public:
  std::unique_ptr<Base> base;
  std::vector<byte> filebuff;
  long buff_size;
  Wrapper();
}

//...

//constructor implementation
WrapperClass::WrapperClass() {
  //do whatever you want to initialize filebuff and buffsize here
  calcfunc();

  //now pass them in to your base class
  base = new Base(filebuff, buffsize);
}

答案 1 :(得分:2)

问题是您在初始化之前尝试使用filebuff,因为基类的构造函数是在非静态成员的构造函数之前调用的。我同意ildjarn的最佳解决方案是用组合替换继承:

class BaseClass {
public:
  BaseClass(const byte *buff, long size) { 
     // Some Computation
  }
};

class YourClass {
public:
  std::vector<byte> filebuff;
  long buff_size;
  BaseClass base;

  DerivedClass()
    : /* initialize filebuff and buff_size */, base(&filebuff[0], buff_size) {}
};

成员将按照它们在类定义中出现的顺序进行初始化,这样您就可以将filebuffbuff_size传递给基础的构造函数。

另见this answer问题“C ++:成员类的初始化顺序”。