Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++: constructor / initializer for array?

I'm familiar with C++ constructors & initializers:

class Foo {
   int x;
public:
   Foo(int _x) : x(_x) {}
};

Foo foo1(37);
Foo foo2(104);

My question is that I have to implement a class that has a member which is a 3x6 array. How would I do something similar to the above?

class Bar {
   int coeff[3][6];
public:
   // what do I do for a constructor????
};

edit: for a plain array, I would do the following, I just don't know how to do it for a class:

 static int myCoeffs[3][6] = 
 {{  1,  2,  3,  4,  5,  6}, 
  {  7,  8,  9, 10, 11, 12},
  { 13, 14, 15, 16, 17, 18}};

edit 2: For various reasons (e.g. this is an embedded system w/ limitations) I need to not use Boost, so if it offers a solution I can't use it.


UPDATE: I'm not tied to an initializer. It's OK to do it in the constructor body, and it doesn't have to be inline, either. I'm just looking for a correct way to construct an instance of a class which needs an array of coefficients, without messing up pointer assignment or something.

like image 541
Jason S Avatar asked Mar 07 '11 16:03

Jason S


People also ask

Can we initialize array in constructor?

Initialize Array in Constructor in Java We can create an array in constructor as well to avoid the two-step process of declaration and initialization. It will do the task in a single statement. See, in this example, we created an array inside the constructor and accessed it simultaneously to display the array elements.

How do you initialized an array in C?

Initializer List: To initialize an array in C with the same value, the naive way is to provide an initializer list. We use this with small arrays. int num[5] = {1, 1, 1, 1, 1}; This will initialize the num array with value 1 at all index.

Do arrays need to be initialized in C?

An array may be partially initialized, by providing fewer data items than the size of the array. The remaining array elements will be automatically initialized to zero. If an array is to be completely initialized, the dimension of the array is not required.

How do you declare an array in a constructor in CPP?

If no default constructor is defined for the class, the initializer list must be complete, that is, there must be one initializer for each element in the array. The first element of aPoint is constructed using the constructor Point( int, int ) ; the remaining two elements are constructed using the default constructor.


4 Answers

You can't. In C++03 you can't initialize an array in a ctor-initalization list. However you can do it in the constructor body (technically it isn't an initialization any more).

That is

struct x
{
    int a[4];
    x():a({1,2,3,4}) //illegal
    {
        a[0] = 1;
        etc. 
    }
};

Edit: after question edit here's a way to do it

#include <algorithm>
struct x
{
   int arr[3][4];
   x(int (&arg)[3][4])
   {
      std::copy(&arg[0][0], &arg[0][0]+3*4, &arr[0][0]);
   }

};
like image 124
Armen Tsirunyan Avatar answered Oct 02 '22 22:10

Armen Tsirunyan


I don't know if it sounds too obvious but, why don't just copy the values?

class Foo {
    static const int X = 3;
    static const int Y = 6;

    int mCoeff[X][Y];

    void setCoeff(int coeff[X][Y]) {
        for (int i = 0; i < X; i++) {
            for (int j = 0; j < Y; j++) {
                mCoeff[i][j] = coeff[i][j];
            }
        }
    }
public:
    Foo(int coeff[X][Y]) {
        setCoeff(coeff);
    }

};

Hope it helps. Regards.

like image 44
redent84 Avatar answered Oct 02 '22 23:10

redent84


In C++03, since you cannot initialize an array in the initialization-list, you can write a generic function template to fill an array with a given array, as demonstrated in the following example,

template<typename T, size_t N>
void array_fill(T (&dest)[N], T (&src)[N])
{
   for ( size_t i = 0 ; i < N ; i++ )
       dest[i] = src[i];
}
struct A
{
   int a[5];
   A(int (&i)[5]) { array_fill(a, i); }
   void print() 
   {
      for ( int i = 0 ; i < 5 ; i++ ) cout << a[i] << " ";
   }
};
int main() {
        int a[5] = {1,2,3,4,5};
        A obj(a);
        obj.print();
        return 0;
}

Output:

1 2 3 4 5

Run at ideone: http://ideone.com/pFcrv

Well, there is already std::copy which can be used as well.

like image 39
Nawaz Avatar answered Oct 02 '22 22:10

Nawaz


You can't (in general) pass the arbitrary multidimensional array to a function in C or C++ as one would in Java (I mention Java because that's where your question history suggests your experience lies).

There's really no way to support anything like array initializers for your class in the current standard, though there are some plans to change this in the next version, C++0x.

If you want this to have the flexibility of, say, Java's arrays (where clients can change the size of the pointed to array, you have a few options. The first and best would to be to use std::vector<>, which implements a dynamic array for you, but you might be restricted on that by your embedded platform. You can also implement things yourself as a single dimensional array, and accept a dynamic memory block. Example:

class Foo
{
    int *theArray_;
    unsigned int rows_;
    unsigned int cols_;
public:
    Foo(int *theArray, int rows, int cols)
        : theArray_(theArray)
        , rows_(rows)
        , cols_(cols)
    { }
    void UseTheArray()
    {
        //Access array[5][6]
        theArray[5*cols+6];
    }
};

Note that in this case the callee is responsible for handing the memory. Also consider using a std::auto_ptr above instead of the raw pointer to make it clear who's responsible for nuking the memory block when the object is destroyed.

Also note that you shouldn't use the name _x - names beginning with an underscore have a whole bunch of rules attached to them about which you probably want to avoid thinking.

EDIT: This is a segment of my original answer; it is wrong:

A multidimensional array in C++ is just a single memory block. It's possible to accept a multidimensional array like this only in one case -- where you know the exact dimensions of the array beforehand in the class. Then you could write something like:

class Foo {
   int coeff[3][6];
public:
   Foo(int _x[3][6]) : coeff(_x) {}
};

Note however that the size of the array is fixed and cannot be changed by clients of your class.

like image 31
Billy ONeal Avatar answered Oct 02 '22 21:10

Billy ONeal