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

C++ 错误:非静态类数据成员的使用无效,c++,vector,C++,Vector,这个错误的所有其他示例都让我想到了“您还没有定义数组大小”,但我没有使用数组,而是使用不同的文件并包括它们 我实际上想做的是遍历2D向量,并获取每个位置的指针(这就是为什么我需要知道行和列) 每次我在Unit.cpp中的以下代码中使用Map::时都会发生错误: #include "Map.h" Unit Unit::nearest_enemy_finder(){ vector <Unit *> enemies; for(int i=0; i<Map::RO

这个错误的所有其他示例都让我想到了“您还没有定义数组大小”,但我没有使用数组,而是使用不同的文件并包括它们

我实际上想做的是遍历2D向量,并获取每个位置的指针(这就是为什么我需要知道行和列)

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

#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.h
中,如果我将static放在变量前面,就会得到一个错误

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)
架构x86_64的未定义符号: “地图::地图方格”,参考自: Map::Map.cpp.o中的init_Map_squares() Map::init\u Map\u来自Map.cpp.o中的\u级别(std::\u 1::basic\u字符串) Map::在Map.cpp.o中设置单位符号(int,int) “映射::单位指针”,引用自: Unit::Unit.cpp.o中最近的敌人查找器() Map.cpp.o中的init_unit_pointers() Map::init\u Map\u来自Map.cpp.o中的\u级别(std::\u 1::basic\u字符串) Map::在Map.cpp.o中设置单位符号(int,int) “映射::行”,引用自: Unit::Unit.cpp.o中最近的敌人查找器() Map.cpp.o中的Map::init(std::\u 1::basic\u字符串) Map.cpp.o中的init_unit_pointers() Map::Map.cpp.o中的init_Map_squares() “映射::列”,引用自: Unit::Unit.cpp.o中最近的敌人查找器() Map.cpp.o中的Map::init(std::\u 1::basic\u字符串) Map.cpp.o中的init_unit_pointers() Map::Map.cpp.o中的init_Map_squares() ld:找不到架构x86_64的符号 叮当声:错误:链接器命令失败,退出代码为1(使用-v查看调用)
您为类
映射定义的类成员以及非
静态的类成员是依赖于类的对象的成员

因此,如果定义两个贴图:

Map a, b; 
每个实例都有自己的

a.ROWS = 10;   // small Map
b.ROWS = 50;   // larger Map  
如果在另一个对象中,您像您一样引用成员(即
Map::ROWS
),编译器会抱怨,因为您没有说出您指的是哪个Map对象的
ROWS

所以您必须解决一个基本的设计问题:
单元
类的对象如何知道要使用哪个
映射
对象

  • 单元
    应具有相关
    地图x的成员参考在施工时?然后您可以澄清:
    x.ROW
    而不是
    Map::ROWS
  • Unit
    是否应该能够从一种存储库中找到?然后,您可以找到正确的对象并按照上面的操作
  • 您要一张
    地图吗?然后使成员
    静态
如果将这些成员设置为静态,则表示它们不再依赖于特定对象,而是在该类的所有对象之间共享。嗯,如果你把
Map
的一切都变成静态的,它就不再是OOP意义上的真正类,而是一种全局变量集的替代品

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

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


p.S:正如评论中提到的,试着

显示你的
Map.h
;我们应该如何知道
Map::
是什么?想象一下,我们没有跟随您,了解您所看到的每一个例子,或者您正试图实现的目标。介意详细说明一下吗?也许要创建一个?所以,首先:不要使用
所有的变量名
。这些是为宏和常量保留的规范。然后:这听起来像是在空闲和内存泄漏后使用的方法。了解智能指针和对象所有权概念。然后,这里真的不需要
静态
成员;如果一个映射只有一个实例,那么创建一个单例映射工厂。如果应该有多个映射,但只有一组敌人,那么您的对象设计很糟糕,您应该将敌人保持在映射之外。而且:我打赌您的编译器(或者更可能是您的链接器)实际上会在“未定义符号”行之前(或者之后)为您提供错误的详细信息。你甚至没有给我们所有的错误信息!我完整地给出了错误消息。我不知道你说的地图工厂是什么意思。我实际上想做的是迭代二维向量,得到每个位置的指针。这就是为什么我需要知道行和列我只有一个映射,只能引用一个映射::行等等。。。如果我声明
intmap::行
然后我收到错误
非好友类成员“ROWS”不能有限定名称
对不起,我的错误,是ROWS。您是否在Map.h中声明为静态,并在Map.cpp的顶层定义了它?并不像我在问题中所说的那样,它给了我一个错误,但我确实声明了它。@MeowWOW这是成对的:或者在标题中声明为静态,然后在所描述的一个cpp中定义它(这将防止您提到的错误)。或者定义一个全局
Map
对象(即在一个cpp中定义Map
my_global\u Map;
,在头文件中定义
extern Map my_global\u Map;
,以便在其他文件中知道它),并使用该对象访问成员(例如
my_global\u Map.行
)。
int Map::ROWS;