Как инициализировать размер массива с использованием конструктора?

156
03 декабря 2021, 07:30

Я хочу при вызове конструктора задать размер массива, находящегося в теле класса. Для этого я пытаюсь использовать указатель p, который бы забирал значение из конструктора. Я делаю это так:

class bigestint
{
    const int* p;
    long long int Body[*p];
    bigestint(const int R)
    {
        p = &R;
    }
};

Ошибка возникает здесь: "long long int Body[*p]". Я пробовал несколько раз добавлять слова const и static к определению p (Так как компилятор ругается на то, что это не const значение или нестатическая ссылка), но на самом деле не понимаю как работает static.

Подскажите как можно исправить/реализовать то что я хочу, и можно ли так делать в принципе. Спасибо.

Answer 1

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

template <size_t SIZE>
class bigestint
{   
    long long  Body[SIZE]{};
    size_t length; //используемый размер
public:
    bigestint(const size_t R) : length(R % (SIZE + 1)) {}
    bigestint() : bigestint(SIZE) {}
    //неиспользованное количество элементов массива
    size_t free_place() const { return SIZE - length; }
    //получение другого типа
    template<size_t sz>
    struct rebind {
        using other = bigestint<sz>;
    };
    size_t size() const { return length; }
    long long* begin()  { return Body; }
    long long* end()  { return &Body[length]; }
    long long &operator [](const size_t index)
    {
        //обработать случай выхода за пределы размера
        if (index >= length)
            throw  std::out_of_range("  ");
        return Body[index];
    }
    //...
};

int main() {
     //занимаем память на 10 элементов, но 
    bigestint<10> arr(8); //используем 8 из них
    for (int i = 0; i < arr.size(); ++i) {
        arr[i] = i;
        cout << arr[i] << ' ';
    }
    //теперь мне нужна и остальная часть массива
    cout <<"\n работа с неиспользованной частью массива\n";
    long long* p = arr.end();
    for (int j = 0; j < arr.free_place(); ++j) {        
        p += j;
        *p = long long(arr.size() + j);
        cout << *p << ' ';
    }
    //но потом, мне понадобился массив побольше(на 15 элементов)
    cout << "\nесли нам нужен массив побольше, переходим на другой тип\n";
    decltype(arr)::rebind<15>::other m; 
    for (int k = 0; k < m.size(); ++k) {
        m[k] = 10 * (long long(k) + 1);
        cout << m[k] << ' ';
    }               
    return 0;
}

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

READ ALSO
Не получается обернуть HANDLE в std::unique_ptr

Не получается обернуть HANDLE в std::unique_ptr

Появилось желание обернуть в RAII классы ряд объектов из WinAPI (хендлы, сертификаты и тд

83
Qt. Частичная перерисовка области

Qt. Частичная перерисовка области

У меня будет простое банковское приложениеИ я решил сделать такой интерфейс:

58
Получение доступа к объекту в приватном поле дружественного класса

Получение доступа к объекту в приватном поле дружественного класса

Есть класс, назовём его FirstclassВ нём, в приватном поле определён структурный тип следующего вида:

194
Сгенерировать N псевдослучайных чисел из диапазона [a;b)

Сгенерировать N псевдослучайных чисел из диапазона [a;b)

Есть ли в питоне/numpy аналог функции std::generate из C++? У меня есть функция без параметров, которая возвращает единственное значениеНадо создать...

73