0
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 只是一个地址这一事实,因此编译器将 func 的计算值首先放在堆栈上还是第一个 arg,filebuff 上并不重要。

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

4

2 回答 2

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);
}
于 2013-03-29T23:37:59.360 回答
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) {}
};

The members will be initialized in the order they appear in the class definition so you'll be able to pass filebuff and buff_size to the base's constructor.

See also this answer to the question "C++: Initialization Order for Member Classes".

于 2013-03-29T23:49:01.870 回答