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];

      

+3


source to share


4 answers


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 }; 

      

+3


source


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;
}

      

+1


source


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.

0


source


You need to create an array of pointers if you want to create an array without creating objects. For example, it aClass** arr = new aClass*[10];

creates an array of pointers. And when you want to create real objects, you need to do something like this:arr[0] = new aClass(2015);

0


source







All Articles