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.
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.
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.
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.
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.
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]);
}
};
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With