Объявить массив фиксированной длины во вложенных классах

У меня есть класс A, который имеет вложенный класс B. Класс A создаст n(параметр времени выполнения) экземпляров класса B.

В конструкторе A после вычислений, которые необходимо выполнить во время выполнения, я вычисляю размер, скажем, s.

Теперь каждый класс B будет содержать массив размером s.

Однако я не могу использовать файлы.cpp, и вся работа должна выполняться в заголовочных файлах.

Это означает, насколько я понимаю, что я не могу использовать этот подход (с static):

class B {

static const int s;
int a[s];

};

Итак, я решил использовать enum, но я не мог заставить его работать (даже с enum class C++11). Идея в том, что вы делаете что-то вроде:

class B {

enum { s = 50 };
int a[s];

};

но я не знаю s до времени выполнения.

Конечно, я мог бы пойти с std::vector или с dynamic allocation,

Но с тех пор:

1) мне нужен только функционал старых добрых массивов (сбрасывает вектор)

2) Я знаю, прежде чем создавать экземпляры B, размер массива (отбрасывает динамическое распределение)

Около std::dynarray обсуждается ниже:

К сожалению не в C++14, но в array TS или же C++17, Источник, кредиты Манлио.

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

4 ответа

Решение

Два массива, имеющие даже один и тот же тип элемента, но с разными размерами, являются разными типами. Так например char[10] а также char[11] разные типы. Точно так же, если два класса имеют член с типом, который отличается между этими двумя классами, классы определяют разные типы и имеют разные размеры (я имею в виду оператор sizeof). Также вы не можете создавать экземпляры объекта неполного типа.

Если ваш компилятор поддерживает класс std::dynarray Я бы посоветовал им воспользоваться. В противном случае вы можете использовать класс std::vector

Вы не можете объявить массив переменного размера в C++. Компилятор должен знать размер массива заранее. использование std::vector вместо этого, а затем использовать std::vector::shrink_to_fit уменьшить его емкость, чтобы соответствовать его размеру.

class B {
  ...
  std::vector<int> a;
  ...
};

Ответ: использовать std::vector, Этот пункт:

1) мне нужен только функционал старых добрых массивов (сбрасывает вектор)

на самом деле не относится. Вам нужна дополнительная функциональность, которой нет у старых хороших массивов (а именно, выделение массива, размер которого у вас есть только во время выполнения).

Если у вас есть последняя компилятор / стандартная библиотека, возможно, у вас есть доступ к <experimental/dynarray>... который, ИМХО, является просто урезанной версией <vector>, но каждому свое:D

Есть два вопроса. Во-первых, обратите внимание, что вложенность классов предназначена только для области видимости. Вложенный класс не создает автоматически член данных этого класса во внешнем классе. Поэтому обычно вы определяете член (ы) во внешнем классе типа вложенного класса, как показано ниже. Во-вторых, вы не можете определить массив на основе размера, который вычисляется во время выполнения в C++.

Тем не менее, вы могли бы легко использовать std::vector, Если по какой-то причине все это должно быть сделано в заголовочном файле, вы можете определить их в классе, хотя это было бы плохой идеей, если бы они содержали более пары строк.

#include <vector>
#include <cstddef>

class A {
    private:
        class B {
            friend A;
            B(size_t n) : array(n) {}
            std::vector<int> array;
        };
    public:
        // Initialize b_member based on some computation.
        A(int i) : b_member(i + 2), b_ptr_member(new B(i + 3)) {}
        ~A() { delete b_ptr_member; }
    private:
        B b_member;
        B *b_ptr_member;
};

int main() {
    A a(10);
}
Другие вопросы по тегам