Alex Rivera | Logout

How do I declare an array of objects whose class has no default constructor?

Asked 2010-02-26T17:36:18.560
14

If a class has only one constructor with one parameter, how to declare an array? I know that vector is recommended in this case. For example, if I have a class

class Foo{

public:
Foo(int i) {}

}

How to declare an array or a vector which contains 10000 Foo objects?

Edit
Report

3 Answers

16

For an array you would have to provide an initializer for each element of the array at the point where you define the array.

For a vector you can provide an instance to copy for each member of the vector.

e.g.

std::vector<Foo> thousand_foos(1000, Foo(42));
answered 2010-02-26T17:48:16.473
8

sbi had the best answer for plain arrays, but didn't give an example. So...

You should use placement new:

char *place = new char [sizeof(Foo) * 10000];
Foo *fooArray = reinterpret_cast<Foo *>(place);
for (unsigned int i = 0; i < 10000; ++i) {
    new (fooArray + i) Foo(i); // Call non-default constructor
}

Keep in mind that when using placement new, you are responsible for calling the objects' destructors -- the compiler won't do it for you:

// In some cleanup code somewhere ...
for (unsigned int i = 0; i < 10000; ++i) {
    fooArray[i].~Foo();
}

// Don't forget to delete the "place"
delete [] reinterpret_cast<char *>(fooArray);

This is about the only time you ever see a legitimate explicit call to a destructor.

NOTE: The first version of this had a subtle bug when deleting the "place". It's important to cast the "place" back to the same type that was newed. In other words, fooArray must be cast back to char * when deleting it. See the comments below for an explanation.

answered 2010-02-26T19:28:22.147
0

If it makes sense for your class, you could provide a default value for your constructor parameter:

class Foo
{ 
public: 
  explicit Foo(int i = 0); 
}

Now you have a default constructor. (A "default constructor" is a constructor that can be called with no arguments: FAQ)

I'd also recommend making your constructor explicit, as I did above. It will prevent you from getting Foos from ints when you don't want request them.

answered 2010-02-26T20:11:53.620

Your Answer