Списки конструктора в определенном порядке с указателями - PullRequest
0 голосов
/ 27 мая 2019

Я пишу код, который использует библиотеку без конструктора по умолчанию (есть, но он скоро устареет и выдает предупреждения), и я хотел бы использовать его внутри класса.Теперь я знаю, что есть несколько ответов для этого в целом, но ни один, кажется, не отвечает на мой конкретный вариант.

Вот почему: конструктор библиотеки получает указатель на два массива, которыеиспользуется для ввода и вывода.Мне нужно выделить память для этих массивов, и я должен сделать это до того, как я вызову конструктор этой библиотеки.

Поэтому мне нужна альтернатива спискам конструкторов, которая позволит мне контролировать порядок, или Мне нужно знать, как выделить память для объектов внутри списка конструкторов.

Вот соответствующий код:

Мой класс:

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 Ответ

3 голосов
/ 27 мая 2019

Порядок инициализации членов данных класса определяется порядком объявления в определении класса. (Порядок инициализаторов членов в конструкторе не влияет на это.) Таким образом, вы можете переставить члены, чтобы сделать что-то вроде:

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 / Rule of Zero, чтобы исправить все это сразу.

#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 по тем же причинам.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...