在类之间访问动态分配的数组时出错

时间:2011-04-15 00:02:54

标签: c++ arrays class 2d

更新:我的大多数相关源代码都在此pastebin中:http://pastebin.com/nhAx1jfG

任何人都可以理解这个错误吗?我正在尝试访问我在同一名称空间中的另一个类中声明的2d“Tile”数组,它是公共的,并且我在主“rouge.cpp”类中声明了一个对象。

g++ -Wall -Werror -lncurses -c rouge.cpp -o rouge.o
rouge.cpp: In function ‘void update_game(Player, Map, World, bool)’:
rouge.cpp:497: error: no match for ‘operator[]’ in ‘*(world.World::tiles + ((((unsigned int)player.Player::<anonymous>.GameObject::x) + 0xffffffffffffffffffffffffffffffffu) * 16u))[player.Player::<anonymous>.GameObject::y]’
rouge.cpp:506: error: no match for ‘operator[]’ in ‘*(world.World::tiles + ((((unsigned int)player.Player::<anonymous>.GameObject::x) + 1u) * 16u))[player.Player::<anonymous>.GameObject::y]’
rouge.cpp:515: error: no match for ‘operator[]’ in ‘*(world.World::tiles + ((unsigned int)(((unsigned int)player.Player::<anonymous>.GameObject::x) * 16u)))[(player.Player::<anonymous>.GameObject::y + -0x00000000000000001)]’
rouge.cpp:524: error: no match for ‘operator[]’ in ‘*(world.World::tiles + ((unsigned int)(((unsigned int)player.Player::<anonymous>.GameObject::x) * 16u)))[(player.Player::<anonymous>.GameObject::y + 1)]’
rouge.cpp:540: error: no match for ‘operator[]’ in ‘*(world.World::tiles + ((unsigned int)(((unsigned int)player.Player::<anonymous>.GameObject::x) * 16u)))[player.Player::<anonymous>.GameObject::y]’
make: *** [rouge.o] Error 1

world.h:

// The "world" class, generates a world.
class World
{
    // Public classes and variables
    public:
        // Tile array
        Tile* tiles;
        int plates[WORLDSIZEX][WORLDSIZEY];
        //Tile tiles[WORLDSIZEX][WORLDSIZEY];
        //Tile (*tiles)[WORLDSIZEX] = new Tile[WORLDSIZEX][WORLDSIZEY];
        // For plates
        //int plates[WORLDSIZEX][WORLDSIZEY];
        //plates = new int[WORLDSIZEX][WORLDSIZEY];
        //int (*plates)[WORLDSIZEX] = new int[WORLDSIZEX][WORLDSIZEY];
        // Small world
        Tile smalltiles[SMALLWORLDX][SMALLWORLDY];
        // For world temp
        int worldtemp;
        // Constructor
        World();
        void generate_plates();
        bool check_plates();
        int build_mountains(int,int);
        void add_mountains();
        void generate_world();
        void shrink_world();
        void save_world();
        void erupt();
        bool get_passable(int,int);
        char get_icon(int,int);
        char get_small_icon(int,int);
        int get_color(int,int);
        int get_small_color(int,int);
};

world.cpp我在哪里分配数组:

// Constructor
World::World()
{
    // Seed for random number
    srand( time(NULL) );
    tiles = new Tile[WORLDSIZEX][WORLDSIZEY];
    // Generate a world
    generate_world();
    // Shrink world
    shrink_world();
    // Then save it.
    //save_world();
}

在rouge.cpp中,我访问它就像:

world.tiles[i][j]; //i and j are ints in a nested for loop

我宣布之后:

World world;

并且它正在吐出错误

3 个答案:

答案 0 :(得分:2)

world.tiles属于Tile *类型。作为二维数组是错误的类型(你需要Tile**,并且需要分两步初始化它(一个用于创建Tile*指针数组,以及一个用于创建数组的循环这些Tile *指针中的每一个都可以指向。

e.g。在你的班级def:

Tile **tiles

例如:在你的构造函数中:

tiles = new Tile*[SMALLWORLDX];
for (int i = 0; i < SMALLWORLDX; i++)
   tiles[i] = new Tile[SMALLWORLDY];

回到导致原始错误的原因 - 当你调用world.tiles[x][y]时,第一个[]运算符没问题,因为tile可能指向Tiles的数组,但是第二个一个不好。

答案 1 :(得分:2)

您正在使用指针指向一个动态分配为多维数组的数组。在多维数组的地址存储在World::tiles之后,编译器“忘记”该数组是多维的。因此,您不能再使用双括号表示法(tiles[x][y])来访问元素。

要解决此问题,您至少有4个选项:

  1. 在World中提供一个方法,它接受x,y坐标并返回对所需单元格的引用(您可能希望同时提供const和非const版本):

    Tile& at(size_t x, size_t y) {return tiles[y*WORLDSIZEX + x];}

    const Tile& at(size_t x, size_t y) const {return tiles[y*WORLDSIZEX + x];}

  2. World::tiles汇总您自己的2D数组类。

  3. World::tiles使用boost::multi_array

  4. World::tiles声明为vector< vector<Tile> >。所有嵌套向量的初始大小都很棘手,但之后您可以使用world.tiles[x][y]表示法。

  5. 另外@fsmc选项给了你。


    我快速查看了pastebin中的代码。如果您初始化这样的tiles向量,那将会更有效(并且看起来更干净):

    tiles.resize(WORLDSIZEX);
    for(int i = 0; i < WORLDSIZEX; i++)
    {
        tiles[i].resize(WORLDSIZEY);
    }
    

答案 2 :(得分:0)

仅基于错误消息,无论您尝试索引的是什么,实际上都不是数组。该语句开头的'*'(取消引用)运算符对我来说很可疑,但如果没有真正看到你的代码,我就不能说太多了。