我正在编写使用没有默认构造函数的库的代码(有,但很快就会弃用,并引发警告),我想在类中使用它。现在,我知道通常有几个答案,但是似乎没有一个答案可以回答我的 specific 变体。
原因如下: 库的构造函数采用一个指向两个用于输入和输出的数组的指针。我需要为这些数组分配内存,并且必须在调用此库的构造函数之前 进行。
因此,我需要构造函数列表的替代方法,使我可以控制顺序,或我需要知道如何为构造函数列表内的对象分配内存。
以下是相关代码:
我的课:
class audio_class{
arduinoFFT FFT;//cannot call constructor HERE, but that leaves the default!
double *real_samples;
double *imaginary;
//--snip--
};
库的构造函数:
arduinoFFT(double *vReal, double *vImag, uint16_t samples, double samplingFrequency);
我的代码的构造函数:
audio_class::audio_class() {
real_samples = new double[READINGS];
imaginary = new double[READINGS];
//Need to initialize arduinoFFT here? Or after allocation of samples, anyway. Constructor list would fire before I call the new[], and the pointers would be invalid. I think?
}
audio_class::~audio_class() {
delete[] real_samples;
delete[] imaginary;
}
答案 0 :(得分:3)
类数据成员的初始化顺序由类定义中的声明顺序确定。 (构造函数中成员初始化程序的顺序对此没有影响。)因此,您可以重新排列成员以执行以下操作:
class audio_class{
double *real_samples;
double *imaginary;
arduinoFFT FFT;
//--snip--
};
audio_class::audio_class() :
real_samples(new double[READINGS]),
imaginary(new double[READINGS]),
FFT(real_samples, imaginary, READINGS, DFLT_FFT_FREQ)
{
}
但是这里有一个不相关的问题:这不是异常安全的。如果第二个new
或arduinoFFT
构造函数抛出异常,则先前的分配将永远不会被删除并泄漏。加上自己处理new
和delete
会比较棘手,并且需要更多代码(至少遵守“三法则”)。因此,我建议在这里使用std::vector
切换到RAII /零规则,一次修复所有问题。
#include <vector>
class audio_class{
std::vector<double> real_samples;
std::vector<double> imaginary;
arduinoFFT FFT;
// No destructor declaration needed.
//--snip--
};
audio_class::audio_class() :
real_samples(READINGS),
imaginary(READINGS),
FFT(real_samples.data(), imaginary.data(), READINGS, DFLT_FFT_FREQ)
{
}
(出于同样的原因,这种方式仍要求FFT
在real_samples
和imaginary
之后声明。)