如何调用带有多个参数的基类构造函数

C++: How to call a base class constructor with more than one argument?

本文关键字:参数 构造函数 基类 何调用 调用      更新时间:2023-10-16
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只是一个地址的事实,因此编译器是先把函数的计算值放在堆栈上,还是把第一个参数filebuff放在堆栈上,这并不重要。

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

看起来你正在尝试包装一个别人写的类(例如在不同的库中),它有两个参数,另一个类(你写的)有一个更干净的接口。我说的对吗?

您建议的解决方案是从另一个基类派生,然后使用派生类来存储放在基类中的参数。上面方法的问题是,当你调用基类构造函数时,派生类还没有完全构造好(即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*std::unique_ptr<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);
}

问题是您试图在初始化之前使用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传递给基类的构造函数。

参见对" c++:成员类的初始化顺序"的回答