在robots.hpp中,我有class
,robots
。我希望每个机器人都有一个指向另一个机器人的指针,最后一个机器人。我也希望每个人都有一个独特的身份。为此,我有一个计算机器人数量的变量。
似乎我无法在类定义中初始化我的静态变量。我查找了如何解决这个问题,并找到了一些建议在robots.cpp中初始化它们的东西。但是,这给了我一个错误,说它们受到保护,所以我无法做到这一点。所以现在我有一个构造函数在开始时只调用一次的函数。
然而,这给我一个错误,说我不能这样做,因为它们还没有被定义。
robots.hpp中的类定义:
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标准(否则cstdint抱怨))
我希望代码能够使poiRobot
指向null
,NumofRobots
等于0。
答案 0 :(得分:0)
您应该能够摆脱static bool hasBeenInitialised;
和bool robot::hasBeenInitialised=false;
以及初始化函数,只需在cpp文件中直接声明uint_least8_t robot::NumOfRobots = 0;
和robot* robot::poiRobot = nullptr
即可。这样他们自己初始化为0并自动为空。正如评论中所提到的,这是有效的,应该能够以这种方式在源文件中定义受保护的静态变量。
编辑:关于您在编辑中发布的代码,看起来您永远不会定义robot :: poiRobot和robot :: NumRobots。您是否尝试过我上面发布的代码?
基本上,项目中的每个cpp文件都必须由编译器编译成翻译单元。然后链接器通过并获取所有翻译单元并将它们链接在一起。任何看到你的机器人类的cpp文件都会看到你已经承诺这两个变量存在于某个地方,因此当你使用它们时它会允许它(就目前而言,它们存在并且很好用) 。当链接器出现时,它将看到对这些变量的引用,并尝试找到它们被定义的转换单元,以便它可以完成其工作(将所有内容链接在一起)。此时,它不会在任何翻译单元中看到定义,这就是它为您提供错误的原因。
uint_least8_t robot::NumOfRobots = 0;
和robot* robot::poiRobot = nullptr
是您要查找的定义,应该放在您的cpp文件中。如果在使用这些之后你会得到另一个关于它们受到保护的错误,就像你之前暗示的那样,发布该代码以便我们可以看到为什么会发生这种情况。
编辑2关于&#34;似乎我无法在类定义中初始化我的静态变量。&#34;:当您将该定义放在头文件中时,包含的每个cpp文件您的标题将定义它自己的变量版本。当链接器链接所有内容时,它将在不同的转换单元中看到同一变量的多个定义,并且违反了&#34;一个定义规则&#34;在C ++(ODR)中。这就是为什么它会给你一个错误。将它放在robots.cpp中是正确的,因此只有1个翻译单元(在本例中为robots.cpp)将具有该定义。然后你必须确保你的项目中正在编译robots.cpp,以便链接器可以使用转换单元...因为你可能错误地只在源文件中包含robots.h,但是从不告诉编译器编译robots.cpp。