gpt4 book ai didi

c++ - 找不到命名空间,尽管它就在那里

转载 作者:太空狗 更新时间:2023-10-29 21:05:21 30 4
gpt4 key购买 nike

我在一个头文件中定义了一个命名空间并在另一个头文件中使用,但找不到它。具体来说,在名为“combat/Targetable.hpp”的文件中找不到在“players/Players.hpp”中定义并在名为“players/Ownable.hpp”的文件中使用的名为“players”的命名空间

错误是

...\source\combat\Targetable.hpp(7): 'players' : is not a class or namespace name
...\source\combat\Targetable.hpp(7): 'Ownable' : base class undefined

显然这是一些我不明白的语法。我花了一些时间来简化代码,所以它看起来很傻,但请耐心等待。

// source/players/Players.hpp:
#ifndef PLAYERS_HPP
#define PLAYERS_HPP

#include "../Headers.hpp"

namespace players {
class Player{

// this class compiles fine.
// There used to be a "Players.cpp" but it's been simplified away

public:
int getID(){ return 0; }
int getTeam(){ return 0; }
string getName(){ return ""; }
Vec3 getColor(){ return Vec3(0.0,0.0,0.0); }
};
}
#endif

还有 players/Ownable.hpp,它与 Player.hpp 在同一个文件夹中,也可以正常编译:

// source/players/Ownable.hpp:
#ifndef OWNABLE_HPP
#define OWNABLE_HPP

#include "Players.hpp"

namespace players {
class Ownable;
typedef boost::shared_ptr<Ownable> OwnablePTR;
typedef boost::weak_ptr<Ownable> OwnableWPTR;

class Ownable {
public:
Ownable(){}
Ownable(int playerID) : playerID(playerID){}
bool isAlliedWith(OwnablePTR other){ return false; }

private:
int playerID;
};
}

#endif

这就是乐趣的开始。我在“source/combat/Targetable.hpp”中有一个文件,它与其他两个位于不同的目录中。但是,该文件本身似乎还不错:

// source/combat/Targetable.hpp:
#ifndef TARGETABLE_HPP
#define TARGETABLE_HPP

#include "../players/Ownable.hpp"

namespace combat{
class Targetable : public players::Ownable { // ERROR
public:
Targetable(int playerID){}
//Targetable(players::Player player);

virtual Vec2 getPosition(){
return Vec2();
}
virtual Vec2 getVelocity(){
return Vec2();
}
};
}

#endif

我真的希望这是我遗漏的一些愚蠢的语法。我什至尝试过

using players::Ownable;

但是 A) 污染了包含这个文件的文件,并且 B) 没有修复任何东西。有帮助吗?

编辑:GManNickG 明白了,它是 Headers.hpp 文件中的循环包含。谢谢!

最佳答案

你有一个循环包含。

首先考虑include guards的目的:

// a.hpp
#ifndef A_HPP
#define A_HPP

// stuff

#endif

// b.hpp
#ifndef B_HPP
#define B_HPP

#include "a.hpp"

// stuff

#endif

// c.hpp
#ifndef C_HPP
#define C_HPP

#include "a.hpp"
#include "b.hpp"

// stuff

#endif

// x.cpp
#include "c.hpp"

c.hpp 的包含将最终包含 a.hpp 两次。第一次,守卫没有定义,一切正常,第二次,守卫阻止重新定义。这就是我们想要的。

但是,当你有一个循环时,这不起作用。 (它会阻止它,这很好,但它做得“太好了”,因为守卫是在其测试后立即定义的,这意味着 header 的内容实际上尚未被处理)。考虑一下:

// a.hpp
#ifndef A_HPP
#define A_HPP

#include "c.hpp"

// stuff

#endif

// b.hpp
#ifndef B_HPP
#define B_HPP

#include "a.hpp"

// stuff

#endif

// c.hpp
#ifndef C_HPP
#define C_HPP

#include "b.hpp"

// stuff

#endif

// x.cpp
#include "c.hpp"

这与您所拥有的相似。 x.cpp包含c.hpp,这是第一次被包含,所以它定义了C_HPP。然后c.hpp包含b.hpp,其中包含a.hpp。然后 a.hpp 包含 c.hpp 并且发现 C_HPP 已经定义了,所以 include 什么都不做.

假设 a.hpp 仍然设法编译(也就是说,实际上不需要 c.hpp),那么 a.hpp完成,然后 b.hpp 完成,然后 c.hpp 在返回到 x.cpp 之前最终真正定义了它的内容。

解决方案是尽量减少包含的 header 数量。使用前向声明,最重要的是:不要使用“包括一切” header !这些都是可怕的。我怀疑 Headers.hpp 就是这样。

关于c++ - 找不到命名空间,尽管它就在那里,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10185191/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com