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

С++, массив объектов без <vector>

Я хочу создать в С++ массив объектов без использования STL.

Как я могу это сделать?

Как я могу создать массив Object2, у которого нет конструктора без аргументов (конструктор по умолчанию)?

4b9b3361

Ответ 1

Если этот тип не имеет конструктора без аргументов, используйте new[]:

Object2* newArray = new Object2[numberOfObjects];

не забудьте вызвать delete[], когда вам больше не нужен массив:

delete[] newArray;

Если у него нет такого конструктора, используйте operator new для выделения памяти, затем вызовите конструкторы на месте:

//do for each object
::new( addressOfObject ) Object2( parameters );

Опять же, не забудьте освободить массив, когда он вам больше не нужен.

Ответ 2

// allocate memory
Object2* objArray = static_cast<Object2*>( ::operator new ( sizeof Object2 * NUM_OF_OBJS ) );
// invoke constuctors
for ( size_t i = 0; i < NUM_OF_OBJS; i++ )
  new (&objArray[i]) Object2( /* initializers */ );

// ... do some work

// invoke destructors
for ( size_t i = 0; i < NUM_OF_OBJS; i++ )
  objArray[i].~Object2();

// deallocate memory
::operator delete ( objArray );

Ответ 3

Предполагая, что ваш класс Base и у вас есть один конструктор аргументов

Base arr[3] = {Base(0), Base(1), Base(2)} ;

Ответ 4

Object2 *myArray[42];
for (int i = 0; i < 42; i++)
{
  myArray[i] = new Object2(param1, param2, ...);
}

Позже вам придется пройти через массив и освободить каждый элемент отдельно:

for (int j = 0; j < 42; j++)
{
  delete myArray[j];
}

Ответ 5

Вы можете сделать то, что std::vector делает, и создать блок необработанной памяти. Затем вы создаете свои объекты, которые не имеют конструктора по умолчанию в этой памяти, используя новое место размещения, поскольку они необходимы. Но, конечно, если вы это сделаете, вы могли бы использовать std::vector в первую очередь.

Ответ 6

Используйте массив указателей для Object2:

std::tr1::shared_ptr<Object2>* newArray = new shared_ptr<Object2>[numberOfObjects];
for(int i = 0; i < numberOfObjects; i++)
{
    newArray[i] = shared_ptr<Object2>(new Object2(params));
}

Или, альтернативно, без использования shared_ptr:

Object2** newArray = new Object2*[numberOfObjects];
for(int i = 0; i < numberOfObjects; i++)
{
    newArray[i] = new Object2(params);
}

Ответ 7

Если конструктор по умолчанию не доступен, вам понадобится массив указателей, а затем цикл над этим массивом для инициализации каждого из указателей.

Ответ 8

Очевидный вопрос заключается в том, почему вы не хотите использовать STL.

Предполагая, что у вас есть причина, вы должны создать массив объектов с чем-то вроде Obj * op = new Obj[4];. Просто не забудьте избавиться от него с помощью delete [] op;.

Вы не можете сделать это с объектом без конструктора, который не принимает аргументы. В этом случае я думаю, что лучше всего вы можете выделить некоторую память и использовать новое место размещения. Это не так просто, как другие методы.

Ответ 9

Если вам действительно нужен массив (непрерывная последовательность объектов) нестандартного конструктивного типа и по какой-то причине вы можете использовать пользователя std::vector (!?), тогда вам нужно использовать функцию выделения и размещения new.

Это очень трудно сделать надежно; это должно помочь показать, почему. Этот фрагмент включает в себя некоторую защиту от исключений, но более чем вероятно не устойчив ко всем отказам.

const size_t required_count = 100; //e.g.

// cast to pointer of required type needed for pointer arithmetic
Object2* objarray = static_cast<Object2*>(operator new(required_count * sizeof(Object2)));

size_t construction_count = 0;

try
{
    while (construction_count < required_count)
    {
        // params could change with index.
        new (static_cast<void*>(objarray + construction_count)) Object2(param1, param2);
        ++construction_count;
    }
}
catch (...)
{
    while (construction_count-- != 0)
    {
        try
        {
            (&objarray[construction_count])->~Object2();
        }
        catch (...)
        {
            // not a lot we can do here, log but don't re-throw.
        }
    }

    operator delete(objarray);
    throw;
}

// Now objarray has been allocated and pointer to an array of required_count Object2
// It cannot be de-allocated via delete[] or delete; you must loop through
// calling destructors and then call operator delete on the buffer.