Подтвердить что ты не робот

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

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

class Class
{
public:
  int array[];
  Class(int x) : ??? { }
}
4b9b3361

Ответ 1

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

Я рекомендую использовать std::vector<int> вместо массива. Он предоставляет массив, подобный синтаксису для большинства операций.

Ответ 2

Вы, ребята, так усложнили это. Конечно, вы можете сделать это на С++. Для него хорошо использовать обычный массив для повышения эффективности. Вектор имеет смысл только в том случае, если он заранее не знает конечный размер массива, т.е. Он должен расти со временем.

Если вы знаете размер массива на один уровень выше в цепочке, шаблонный класс является самым простым, потому что нет динамического выделения и нет возможности утечки памяти:

template < int ARRAY_LEN > // you can even set to a default value here of C++'11

class MyClass
  {   
  int array[ARRAY_LEN]; // Don't need to alloc or dealloc in structure!  Works like you imagine!   
  }

// Then you set the length of each object where you declare the object, e.g.

MyClass<1024> instance; // But only works for constant values, i.e. known to compiler

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

class MyClass
  {
  int *array;

  MyClass(int len) { array = calloc(sizeof(int), len); assert(array); }   
  ~MyClass() { free(array); array = NULL; } // DON'T FORGET TO FREE UP SPACE!
  }

Ответ 3

Используйте новый оператор:

class Class
{
   int* array;
   Class(int x) : array(new int[x]) {};
};

Ответ 4

Разве вы не понимаете, что нет необходимости использовать вектор, если вы хотите использовать массивы, это вопрос эффективности, например. меньше места, времени на копирование (в таком случае, если правильно обрабатывать, нет необходимости даже удалять массив внутри деструктора) и т.д. по всем причинам.

правильный ответ: (цитируется)

class Class
{
   int* array;
   Class(int x) : array(new int[x]) {};
};

Не пытайтесь заставить использовать не оптимальные альтернативы, или вы будете путать неопытных программистов

Ответ 5

Я не думаю, что это можно сделать. По крайней мере, не так, как ты хочешь. Вы не можете создать массив статического размера (массив []), когда размер поступает из динамической информации (x).

Вам нужно либо сохранить указатель-на-int, и размер, и перегрузить конструктор копирования, оператор присваивания и деструктор для его обработки или использовать std::vector.

class Class
{
  ::std::vector<int> array;
  Class(int x) : array(x) { }
};

Ответ 6

Извините за некроз этой старой темы. Фактически существует способ узнать размер времени компиляции массива. Это происходит примерно так:

#include <cstdlib>

template<typename T>
    class Class
    {
        T* _Buffer;

        public:
        template<size_t SIZE>
            Class(T (&static_array)[SIZE])
            {
                _Buffer = (T*)malloc(sizeof(T) * SIZE);

                memcpy(_Buffer, static_array, sizeof(T) * SIZE);
            }

            ~Class()
            {
                if(_Buffer)
                {
                    free(_Buffer);
                    _Buffer = NULL;
                }
            }
    };

int main()
{
    int int_array[32];
    Class<int> c = Class<int>(int_array);

    return 0;
}

В качестве альтернативы, если вы ненавидите malloc/new, то вместо этого вы можете создать шаблон с шаблоном размера. Хотя, я бы не рекомендовал его, и синтаксис довольно уродлив.

#include <cstdio>

template<typename T, size_t SIZE>
    class Class
    {
        private:
            T _Array[sz];
        public:
            Class(T (&static_array)[SIZE])
            {
                memcpy(_Array, static_array, sizeof(T) * SIZE);
            }
    };

int main()
{
    char int_array[32];
    Class<char, sizeof(int_array)> c = Class<char, sizeof(int_array)>(int_array);
    return 0;
}

В любом случае, я надеюсь, что это было полезно:)

Ответ 7

Вместо использования необработанного массива, почему бы не использовать вместо него вектор.

class SomeType {
  vector<int> v;
  SomeType(size_t x): v(x) {}
};

Использование вектора даст вам автоматическую защиту от утечки перед лицом исключения и многих других преимуществ над необработанным массивом.

Ответ 8

Вы не можете сделать это на С++ - вместо этого используйте std::vector:

#include <vector>

struct A {
   std::vector <int> vec; 
   A( int size ) : vec( size ) {
   }
};

Ответ 9

Объявите свой массив как указатель. Вы можете инициализировать его в списке инициализаторов позже через новый.

Лучше использовать вектор для неизвестного размера.

Возможно, вы захотите посмотреть этот вопрос на массивы переменной длины.

Ответ 10

Два варианта:

Используйте std::vector. Это позволяет легко переустановить массив.
Используйте std:: tr1:: array. Это статический размер.

Оба могут быть правильно инициализированы в списке инициализаторов конструкторов.