开发者

C++: constructor / initializer for array?

开发者 https://www.devze.com 2023-02-15 19:59 出处:网络
I\'m familiar with C++ constructors & initializers: class Foo { int x; public: Foo(int _x) : x(_x) {}

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.


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 have to go that way, I would just go for a for loop iterating the elements of the bi-dimensional array and initializing them. Or if if you're going for speed, something like a memset would do the trick.

memset(&coeff,0,3*6*sizeof(int)) 


You can do it this way:

#include <algorithm>
class Bar 
{    
    int coeff[3][6]; 
public:    // what do I do for a constructor???? 
    Bar()
    {
        int myCoeffs[3][6] = 
        {
            {  1,  2,  3,  4,  5,  6},    
            {  7,  8,  9, 10, 11, 12},   
            { 13, 14, 15, 16, 17, 18}
        }; 
        std::swap(coeff, myCoeffs);
    }
};
0

精彩评论

暂无评论...
验证码 换一张
取 消