开发者

populating int array that is a member variable

I'm using C++ to create a tile map for a game. My problem is, I want to populate a multidimensional array of ints in the Map constructor, but it's not working properly. Here's my code in "Map.h" (irrelevant code has been removed).

class Map {

private:    
int mapArray[15][20];
        
};

And my code from Map.cpp

Map::Map()
{

    mapArray = {
        { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19 },
        { 20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39 },
        { 40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59 },
        { 60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79 },
        { 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99 },
        { 100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119 },
        { 120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139 },
        { 140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159 },
        { 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179 },
        { 180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199 },
        { 200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219 },
        { 220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239 },
        { 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259 },
        { 260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279 },
        { 280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299 }
    };

    
}

PS. creating the mapArray locally开发者_运维百科, within a member function using int mapArray[15][20] and populating it then is working fine, I just can't seem to get it to populate in the constructor, with a member variable.

PPS. Very rusty with C++, please be gentle.

What am I doing wrong?


You can't use array initializers like that in a class constructor. Members can only be initialized by using the initializer list. Your best bet is to load this data from a file, or to declare the array as static.

class Map
{
private:
static int mapArray[15][20];
/* ... */
};

Then define storage for the static array in a source file (.cpp), also known as a translation unit:

int Map::mapArray[15][20] = { ... };


You should be able to do something like this:

class Map
{
  int mapArray[15][20];

  public:
  Map() : mapArray( (int[15][20]) {
    { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19 },
    { 20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39 },
    { 40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59 },
    { 60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79 },
    { 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99 },
    { 100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119 },
    { 120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139 },
    { 140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159 },
    { 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179 },
    { 180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199 },
    { 200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219 },
    { 220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239 },
    { 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259 },
    { 260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279 },
    { 280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299 }
  } )
  {
  }
};

Note that this initialization style is part of C99 and may not be included with your compiler or may not work for C++. Works on GCC 4 for me.

Also note that I did not compile this code. I adapted it for your case from some other code of mine that does work though.


You can use the brace syntax only for initialization.

When your constructor is executed, the array member has alredy been created.


Unfortunately, there's no syntax to do exactly that in C++ for member non-static arrays. You can assign the initial values to array members one-by-one, but that, of course, is quite cumbersome.

If the array values are the same in all objects of that class, then you probably need a static member array. See the answer from Mads then.

If you really need a non-static member array, meaning that you want to be able to "customize" the contents of the array on per-object basis by modifying it later or by initializing it differently, then you can try doing this

class Map {
  static const int MapArrayInit[15][20];
  int MapArray[15][20];

public:
  Map() 
  {
    assert(sizeof MapArray == sizeof MapArrayInit); // better: STATIC_ASSERT
    std::memcpy(MapArray, MapArrayInit, sizeof MapArray);
    // Now you can customize MapArray to your liking
  }
};

and in one of the implementation files

const int Map::MapArrayInit = { /* whatever */ };

This will require extra memory for MapArrayInit, but since you are instatiating a separate MapArray in each instance of Map anyway it is not a big deal.

If you don't want to modify your MapArray after initialization but still want to have several different versions of MapArray contents in different instances of `Map', you can use the following approach

class Map {
  static const int MapArrayInit1[15][20];
  static const int MapArrayInit2[15][20];
  static const int MapArrayInit3[15][20];
  const int (&MapArray)[15][20]; // or a pointer

public:
  Map() : MapArray(MapArrayInit1) /* or 2, or 3 */
  {
  }
};

and in one of the implementation files

const int Map::MapArrayInit1 = { /* whatever */ };
const int Map::MapArrayInit2 = { /* whatever */ };
const int Map::MapArrayInit3 = { /* whatever */ };

Choose whatever works best for you.


You can only use curly brace syntax if you're initializing the array at declaration. In your constructor, you're not. You probably want to load map data from a file anyways instead of hard coding.


This is an assignment, not an initialization. Simple brace initializers only work during initialization. Use the compound literal syntax, which resembles a typecast (to the aggregate you want to initialize) followed by a brace initializer.

Map::Map()
{

    mapArray = (int[15][20]) {
        { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19 },
        { 20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39 },
        { 40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59 },
        { 60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79 },
        { 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99 },
        { 100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119 },
        { 120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139 },
        { 140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159 },
        { 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179 },
        { 180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199 },
        { 200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219 },
        { 220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239 },
        { 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259 },
        { 260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279 },
        { 280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299 }
    };    
}
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜