构造函数按特定顺序列出指针

时间:2019-05-27 01:04:04

标签: c++ constructor

我正在编写使用没有默认构造函数的库的代码(有,但很快就会弃用,并引发警告),我想在类中使用它。现在,我知道通常有几个答案,但是似乎没有一个答案可以回答我的 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;
}

1 个答案:

答案 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)
{
}

但是这里有一个不相关的问题:这不是异常安全的。如果第二个newarduinoFFT构造函数抛出异常,则先前的分配将永远不会被删除并泄漏。加上自己处理newdelete会比较棘手,并且需要更多代码(至少遵守“三法则”)。因此,我建议在这里使用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)
{
}

(出于同样的原因,这种方式仍要求FFTreal_samplesimaginary之后声明。)