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

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

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

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

31
задан osgx 23 March 2010 в 17:34
поделиться

9 ответов

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

Object2* newArray = new Object2[numberOfObjects];

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

delete[] newArray;

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

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

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

34
ответ дан 27 November 2019 в 21:56
поделиться

Используйте массив указателей на 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);
}
3
ответ дан 27 November 2019 в 21:56
поделиться

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

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

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.
0
ответ дан 27 November 2019 в 21:56
поделиться

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

Base arr[3] = {Base(0), Base(1), Base(2)} ;
12
ответ дан 27 November 2019 в 21:56
поделиться

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

3
ответ дан 27 November 2019 в 21:56
поделиться
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
ответ дан 27 November 2019 в 21:56
поделиться
// 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 );
13
ответ дан 27 November 2019 в 21:56
поделиться

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

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

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

0
ответ дан 27 November 2019 в 21:56
поделиться

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

0
ответ дан 27 November 2019 в 21:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: