tags:

views:

144

answers:

4

Why do I have to provide default ctor if I want to create an array of objects of my type? Thanks for answers

+8  A: 

Because they have to be initialized.

Consider if it wasn't the case:

struct foo
{
    foo(int) {}

    void bar(void) {}
};

foo a[10];
foo f = a[0]; // not default-constructed == not initialized == undefined behavior

Note you don't have to:

int main(){
   // initializes with the int constructor
   foo a[] = {1, 2, 3};
}

// if the constructor had been explicit
int main(){
   // requires copy-constructor
   foo a[] = {foo(1), foo(2), foo(3)};
}

If you really need an array of objects and you can't give a meaningful default constructor, use std::vector.

If you really need an array of of objects, can't give a meaningful default constructor, and want to stay on the stack, you need to lazily initialize the objects. I have written such a utility class. (You would use the second version, the first uses dynamic memory allocation.)

For example:

typedef lazy_object_stack<foo> lazy_foo;

lazy_foo a[10]; // 10 lazy foo's

for (size_t i = 0; i < 10; ++i)
{
    // create a foo, on the stack, passing `i` to the constructor
    a[i].create(i); 
}

for (size_t i = 0; i < 10; ++i)
    a[i].get().bar(); // and use it

// automatically destructed, of course
GMan
+1 for the username (and the answer, but that is secondary)
Yacoby
But what you're saying " a[0]; // not default-constructed == not initialized == undefined behavior! " it doesn't really convince me since this isn't true for primitives. So is it ok with primitives to have undefined behaviour but not with user define types? How shall I understand this approach? And what if I do not want to have dflt ctor?
There is nothing we can do
@atch: POD types have no initialization. The lifetime of a POD starts once space exists for it.
GMan
Are you sure that primitives are POD's? I was always convinced that POD is something like structure with data only without anything else;
There is nothing we can do
@atch: Yes, "GMan - Save the Unicorns" is quite sure, as am I :)
Billy ONeal
+2  A: 

The default constructor will be called for each object in the array. You don't have to specify a default constructor as one will be created for you.

Just make sure you don't declare a constructor with no parameters as private or protected.

Here's an example of one being created for you:

class C
{
};


C c[10];

Whereas if you make it private you get a compiling error:

class C
{
private:
    C()
    {

    }
};

C c[10];
Brian R. Bondy
A: 

Because when the array is initialized, default constructors are called for its items.

wRAR
+1  A: 

When defining an array, you cannot specify ctor parameter, hence every object in the array must be constructed using the default ctor.

Normally, the C++ compiler will create the default ctor for you automatically. But, if you define a ctor with parameters, then the automatically creation of the default ctor is supressed, and you must explicitly write one.

James Curran
You can specify a value to initialize with.
GMan
@GMan: Is that one of those things they added in C++0X? I've been doing C# so long, I haven't kept up....
James Curran