对受保护静态成员的未定义引用.我该如何解决
undefined reference to protected static member. How do I solve it?
在robots.hpp中,我有一个class
,robots
。我希望每个机器人都有一个指向另一个机器人的指针,即最后声明的那个机器人。我还希望每个人都有一个唯一的id。为此,我有一个统计机器人数量的变量。
我似乎无法在类定义中初始化我的静态变量。我查了一下如何解决这个问题,发现有人建议在robots.cpp中初始化它们。然而,这给了我一个错误,说它们受到了保护,所以我不能这么做。所以现在我有一个函数,它在一开始只被构造函数调用一次。
但是,这给了我一个错误,说我不能这么做,因为它们还没有定义。
robots.hp:中的类定义
class robot
{
public:
///initialiser.
robot();
[...]
///initialises all robots
void initrobots();
///id of robot
const uint_least8_t id=NumOfRobots++;
static bool hasBeenInitialised;
protected:
///number of robots.
static uint_least8_t NumOfRobots;
///pointer to the next robot that needs pointing to.
static robot* poiRobot;
[...]
///pointer to next robot
robot* nextRobot;
};
robots.cpp:
bool robot::hasBeenInitialised=false;
void robot::initrobots(){
poiRobot=NULL;
NumOfRobots=0;
}
robot::robot(){
if(!hasBeenInitialised){
initrobots();
hasBeenInitialised=true;
}
[...]
}
产生此错误的代码如下:
#include <cstdint>
#include <cstdlib>
class robot
{
public:
///initialiser.
robot();
//[...]
///initialises all robots
void initrobots();
///id of robot
const uint_least8_t id=NumOfRobots++;
static bool hasBeenInitialised;
protected:
///number of robots.
static uint_least8_t NumOfRobots;
///pointer to the next robot that needs pointing to.
static robot* poiRobot;
//[...]
///pointer to next robot
robot* nextRobot;
};
bool robot::hasBeenInitialised=false;
void robot::initrobots(){
poiRobot=NULL;
NumOfRobots=0;
}
robot::robot(){
if(!hasBeenInitialised){
initrobots();
hasBeenInitialised=true;
}
}
int main(){
return 0;
}
如果我编译它,它不会抱怨,但如果我构建它,它会抱怨(使用geany单独做事情,c++11标准(否则cstilt会抱怨)
我希望代码使poiRobot
成为指向null
的指针,并且NumofRobots
等于0。
您应该能够去掉static bool hasBeenInitialised;
和bool robot::hasBeenInitialised=false;
以及初始化函数,只需在cpp文件中直接声明uint_least8_t robot::NumOfRobots = 0;
和robot* robot::poiRobot = nullptr
。通过这种方式,它们会自动将自己初始化为0和null。正如注释中提到的,这是有效的,受保护的静态变量应该能够以这种方式在源文件中定义。
编辑:关于你在编辑中发布的代码,看起来你从来没有定义robot:poiRobot和robot:NumRobots。你试过我上面发布的代码了吗?
基本上,项目中的每个cpp文件都必须由编译器编译成一个翻译单元。然后链接器通过并获取所有的翻译单元,并将它们链接在一起。任何看到你的robot类的cpp文件都会看到你已经承诺这两个变量存在于某个地方,因此当你使用它们时,它会允许它(就目前而言,它们存在并且很好使用)。当链接器出现时,它会看到对这些变量的引用,并试图找到它们是在哪个翻译单元中定义的,这样它就可以完成自己的工作(将所有内容链接在一起)。在这一点上,它不会在任何翻译单元中看到定义,这就是为什么它会给你这个错误。
uint_least8_t robot::NumOfRobots = 0;
和robot* robot::poiRobot = nullptr
是您要查找的定义,应该放在您的cpp文件中。如果在使用这些代码后,你会发现另一个关于它们受到保护的错误,就像你之前暗示的那样,请发布该代码,这样我们就可以看到为什么会发生这种情况。
编辑2关于"我似乎无法在类定义中初始化我的静态变量。":当你把定义放在头文件中时,每个包含你的头的cpp文件都会定义它自己的变量版本。当链接器链接所有内容时,它将看到同一变量的不同翻译单元中的多个定义,这违反了C++(ODR)中的"一个定义规则"。这就是为什么它会给你一个错误。把它放在robots.cpp中是正确的,所以只有一个翻译单元(在这种情况下是robots.cpp)会有这个定义。然后,你必须确保在你的项目中编译robots.cpp,以便链接器可以使用翻译单元。。。因为你可能会错误地在源文件中包含robots.h,但永远不要告诉编译器编译robots.cpp.
- 运行同一解决方案的另一个项目的项目
- Project Euler问题4的错误解决方案
- Ardunio UNO解决了多个重叠的定时器循环
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- 两个文件使用彼此的功能-如何解决
- 计算每个节点的树高,帮助我解释这个代码解决方案
- 如何解决"invalid conversion from 'char' to 'const char*'"
- 在java中解决这段代码时面临循环中的问题
- C++:Application.cpp中抛出了未解析的外部符号(解决方案在问题的末尾,供未来的读者参考)
- 难以理解某些人解决IOI问题的源代码
- visual c++,如何获取解决方案目录中的代码
- 如何解决错误:SCIP C++中的 SCIP 阶段无效 <10>
- 节俭并发:未解决的外部问题
- IpOpt拒绝解决不受约束的问题
- 如何解决这个超硬恒星的创造问题
- 循环无限运行C++解决骑士之旅问题
- 有没有办法在远程设备上打开和编辑visual Studio 2017解决方案
- C++Matching Brackets 2解决方案不起作用
- 在 ubuntu3 上C++ goto 定义有什么解决方案吗16.04?
- 为什么这段代码不起作用,我该如何解决?