错误:无效使用非静态类数据成员

时间:2018-01-21 18:44:19

标签: c++ vector

这个错误的所有其他例子让我得到了“你还没有定义数组大小”,但我没有使用数组,而是使用不同的文件并包含它们。

我真正想做的是遍历2D向量并获取每个位置的指针(这就是我需要知道行和列的原因)

每次我在Map::的以下代码中使用Unit.cpp时都会发生错误:

#include "Map.h"

Unit Unit::nearest_enemy_finder(){

    vector <Unit *> enemies;

    for(int i=0; i<Map::ROWS; i++){
        for(int j=0; j<Map::COLUMNS; j++){
            if (Map::UNIT_POINTERS[j][i]->UNIT_TYPE != UNIT_TYPE){
                enemies.push_back(Map::UNIT_POINTERS[j][i]);
            }
        }
    }
    return *enemies[0];
}

Map.cpp ROWS初始化为5COLUMNS初始化为10UNIT_POINTERSUnit的2D向量}指针:vector<vector<Unit *> >MAP_SQUARESchars的二维向量:vector<vector<char> >

Map.h

class Map
{
public:
    Map(string text_file);
    ~Map();

    vector <vector<Unit *> > UNIT_POINTERS;
    vector < vector<char> > MAP_SQUARES;

    int ROWS;
    int COLUMNS;

private:

    void init(string text_file);

    void init_map_from_level(string text_file);

    void init_unit_pointers();
    void init_map_squares();
};

然而,在Map.h中,如果我在变量的前面放置静态,我会收到错误。

Undefined symbols for architecture x86_64:
  "Map::MAP_SQUARES", referenced from:
      Map::init_map_squares() in Map.cpp.o
      Map::init_map_from_level(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) in Map.cpp.o
      Map::set_unit_symbols(int, int) in Map.cpp.o
  "Map::UNIT_POINTERS", referenced from:
      Unit::nearest_enemy_finder() in Unit.cpp.o
      Map::init_unit_pointers() in Map.cpp.o
      Map::init_map_from_level(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) in Map.cpp.o
      Map::set_unit_symbols(int, int) in Map.cpp.o
  "Map::ROWS", referenced from:
      Unit::nearest_enemy_finder() in Unit.cpp.o
      Map::init(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) in Map.cpp.o
      Map::init_unit_pointers() in Map.cpp.o
      Map::init_map_squares() in Map.cpp.o
  "Map::COLUMNS", referenced from:
      Unit::nearest_enemy_finder() in Unit.cpp.o
      Map::init(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) in Map.cpp.o
      Map::init_unit_pointers() in Map.cpp.o
      Map::init_map_squares() in Map.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

1 个答案:

答案 0 :(得分:0)

您为类Map定义但不是static的类成员是依赖于类的对象的成员。

因此,如果您定义两个地图:

Map a, b; 

每个实例都有自己的ROW

a.ROWS = 10;   // small Map
b.ROWS = 50;   // larger Map  

如果在另一个对象中你引用了一个像你一样的成员(即Map::ROWS),编译器会抱怨,因为你没有告诉你的意思是哪个Map对象ROWS

所以你必须解决一个基本的设计问题:Unit类的一个对象如何知道使用哪个Map对象?

  • Unit在施工时应该有成员参考相关的Map x;吗?然后,您可以澄清:x.ROW而不是Map::ROWS
  • Unit能从某种存储库中找回来吗?然后你可以找回正确的对象,并按上述方式执行。
  • 你会有一个Map吗?然后创建成员static

如果您创建这些成员static,则意味着它们不再依赖于特定对象,而是在该类的所有对象之间共享。恕我直言,如果你使Map的所有东西都是静态的,它就不再是OOP意义上的真正的类,而是一种全局变量集的替代品。

但是如果你这样做,那么每个静态变量不仅必须在类定义中声明,还要在某个地方定义。所以你必须添加如下声明:

int Map::ROWS;   

如果只添加static关键字,编译器将接受它。如果它没有在cpp中定义,它会认为还有一些其他编译单元,您可以在其中定义它。但是,当链接代码时,在构建过程结束时,链接器将找不到符号,因此会显示您观察到的错误消息。

P.S: 正如评论中提到的那样,请尝试avoid all caps symbols