views:

620

answers:

6

Hi all,

Let's say I have an array of objects declared in my header. The size of the array could be very large. In my source file, I create the constructor for my class and I'd like to initialize all the objects in my array. If these objects are not being constructed with a zero-parameter constructor, I am told these need to be put in my initialization list.

My question is if I want to use a loop to initialize this possibly large array of objects, that wouldn't go in the initialization list, would it? I wouldn't want to put in my initialization list: str1("1"), str2("2"), ... , strn("n"). Could a loop to initialize all these objects go in the header or possibly in the body of the constructor?

Please let me know. I have not seen an example of this.

Thanks, jbu

+4  A: 

You are not able to loop in an initializer list, however there is no issue with looping in the constructor body, so long as the object type has a valid assignment operator. The objects in the array will be first initialized using their zero-parameter constructor, before the constructor body. Then in the body you will re-assign them to whatever they need to be.

Also note that if each object in the array is to be initialized using the same NON-zero parameter constructor, you can use an std::vector type, and in the initializer list, specify the default non-zero constructor to be used when allocating the internal array, ie:

// in .h

class MyClass
{
...
    MyClass();

private:

    vector<SomeObject> objects;
};

// in .cpp

MyClass::MyClass()
: objects(100,SomeObject(10, "somestring"))
{
}
DeusAduro
A: 

Not a "newbie" answer, nor one I would use, but you can have a look at the boost preprocessor library, which allows you to create loops with the preprocessor.

Zed
+1  A: 

You cannot initialize arrays in an initialization list. You have to do it in the body of the constructor.

If the thing you want to have an array of is not default-constructable, the simplest solution is to use a std::vector instead of a raw array. That way you can construct the elements as you add them within the constructor body.

But if you insist on having as a class member a raw array of objects whose type does not have a default constructor, then your only real option is to make it an array of pointers-to-Foo rather than an array of Foo.

Tyler McHenry
+4  A: 

you'll have to wait for C++0x to initialize an array in the initializer list.

struct S { 
    int a[3]; 
    S(int x, int y, int z) :a{x,y,z} { /*…*/ }; // solution to old problem 
};
TimW
+3  A: 

It is possible to do like this using boost assign to declare a const vector of elements :

#include<vector>
#include<iostream>
#include<boost/foreach.hpp>
#include<boost/assign.hpp>
#include<boost/assign/list_of.hpp>
#include<boost/assign/std/vector.hpp>

using namespace std;
using namespace boost;
using namespace boost::assign;

typedef vector<int> int_vector;

const int_vector my_const_vector = list_of
(1)(2)(3)(5)(8)(13)(21)(34)(55)(89);

class myClass
{
    public :
      // initialization list used in the constructor
      myClass(const int_vector & vec) 
        : m_member_vector(int_vector(vec.begin(), vec.end())) 
      {}
      void print() const 
      { 
           BOOST_FOREACH(int i, m_member_vector) 
           { cout << i << endl; } 
      }
    private :
      int_vector m_member_vector;
};

void main()
{
   myClass m(my_const_vector);
   m.print();
}

You can get boost from here . I realize this isn't arrays but this does solve your problem - in a way

Maciek
A: 

From your question it looks like you'd like to initialize each element of the array with a different parameter (as implied by the list str1("1"), str2("2"), strn("n")). This is not possible with the current C++; And as TimW noted C++0X will allow support for this type of initialization via sequence constructors.

Having said that, it seems what you want to do is run-time initialization of these values ("1"), ("2")...("n") (Do you know these values at compile time?). If that's the case, I don't think you can use an initialization list even in C++0X. If that's not the case(compile time parameter passing for this very large array), then the preprocessor magic is the way to go.

kvs