Array elements are automatically created by default constructor?
I have a class say aClass
class aClass
{
public:
int data;
aClass(): data(-1) { //default constructor
}
aClass(int x): data(x) { //int constructor
};
If I create an array like
aClass* arr=new aClass[10];
Question 1: I thought the object was aClass
not created as it is just an array declaration, but in the program under test it looks like arr[0]
to arr[9]
, everything points to an object aClass
created by the default constructor in its class? Because I tested the program and the result is a[0].data=-1
completely consistent a[9].data=-1
.
Question 2: If objects are created using their default constructor, how should I create an array with objects created by the int constructor? obviously i can't write code like
aClass* arr=new aClass(2015)[10];
source to share
Quesntion 1: I thought the aClass object was not created as this is just an array declaration
You thought wrong. This is a pointer declarationwhich is initialized with a return value new aClass[10]
, which builds an array of 10 objects.
but in the program I tested it looks like arr [0] so that arr [9] all points to the aClass object created by the default constructor in its class?
Yes, your observation is correct.
Question 2: If objects are created using their default constructor, how should I create an array with objects created by the int constructor?
Since C ++ 11 you can use list initialization: aClass *foo = new aClass[3]{1, 2, 3};
as stated in chris comment.
You can use std :: vector instead. For building copies exists std::vector::vector(size_type n, const value_type& val)
, and C ++ 11: std::vector::vector(initializer_list<value_type>)
for different values.
With static / auto arrays, aggregate initialization is possible even up to C ++ 11:
aClass foo[3] = { 1, 2, 3 };
source to share
Instead, aClass* arr=new aClass(2015)[10];
you can do aClass *arr = new aClass[10]{2015, 2015/*etc*/};
it if your compiler supports it.
In C ++ 11, they both mean the same thing.
aClass *arr = new aClass[10];
aClass *arr = new aClass[10]{};
A better alternative would be to use std::vector
and avoid using raw pointers and use ex smart pointers instead. std::unique_ptr
...
An example of this alternative might be:
int main()
{
vector<unique_ptr<aClass>> vec;
for (int i{0}; i != 10; ++i)
vec.emplace_back(new aClass(2015));
for (auto const& i : vec) // print data
cout << i->data << endl;
return 0;
}
source to share
Regarding question 1. The rules for initialization are very strict. An array expression new[]
creates an array of values. These values ββmust be initialized and they use default initialization by default .
The answer to question 2 is that you cannot do this with dynamic arrays. However std::vector
, it does provide a constructor that allows you to provide an object that will be copied to each of the contained elements. See explicit vector(size_type count, const T& value = T(), const Allocator& alloc = Allocator())
.
If you want each item in the collection to be different, then you must use a loop and assign the items individually, unless the size of the array is statically determined, in which case you can use initializer expressions. If you want to avoid the original default construct for dynamic containers, you shouldn't store objects by value. You should use a pointer container, or better yet, a smart pointer container. Then you can use direct initialization for each object.
source to share