Hello
I want to create in C++ an array of Objects without using STL.
How can I do this?
How could I create array of Object2, which has no argumentless constructor (default constructor)?
Hello
I want to create in C++ an array of Objects without using STL.
How can I do this?
How could I create array of Object2, which has no argumentless constructor (default constructor)?
If the type in question has an no arguments constructor, use new[]
:
Object2* newArray = new Object2[numberOfObjects];
don't forget to call delete[]
when you no longer need the array:
delete[] newArray;
If it doesn't have such a constructor use operator new
to allocate memory, then call constructors in-place:
//do for each object
::new( addressOfObject ) Object2( parameters );
Again, don't forget to deallocate the array when you no longer need it.
If no default constructor is available, you will need an array of pointers, and then loop over that array to initialize each of the pointers.
Object2 *myArray[42];
for (int i = 0; i < 42; i++)
{
myArray[i] = new Object2(param1, param2, ...);
}
Later on you will have to walk through the array and deallocate each member individually:
for (int j = 0; j < 42; j++)
{
delete myArray[j];
}
The obvious question is why you don't want to use the STL.
Assuming you have a reason, you would create an array of objects with something like Obj * op = new Obj[4];
. Just remember to get rid of it with delete [] op;
.
You can't do that with an object with no constructor that doesn't take arguments. In that case, I think the best you could do is allocate some memory and use placement new. It isn't as straightforward as the other methods.
Use an array of pointers to 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));
}
Or, alternatively, without the use of shared_ptr:
Object2** newArray = new Object2*[numberOfObjects];
for(int i = 0; i < numberOfObjects; i++)
{
newArray[i] = new Object2(params);
}
You can do what std::vector
does and create a block of raw memory. You then construct your objects which don't have a default constructor in that memory using placement new, as they are required. But of course, if you do that you might as well have used std::vector
in the first place.
Assuming that your class is Base and you have a one argument constructor
Base arr[3] = {Base(0), Base(1), Base(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 );
If you genuinely need an array (contiguous sequence of objects) of a non-default constructible type and for some reason you cannoy user std::vector
(!?) then you have to use a raw allocation function and placement new.
This is very hard to do reliably; this should help to show why. This snippet includes some defence against exceptions but is more than likely not robust against all failures.
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.