C++ 前向声明错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4197106/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C++ forward declaration error
提问by John Dibling
I have an error that goes like this
我有一个像这样的错误
In file included from Level.hpp:12,
from main.cpp:4:
Corridor.hpp: In method `void Game::Corridor::update()':
Corridor.hpp:41: invalid use of undefined type `class Game::Level'
Corridor.hpp:13: forward declaration of `class Game::Level'
Corridor.hpp:42: invalid use of undefined type `class Game::Level'
Corridor.hpp:13: forward declaration of `class Game::Level'
Corridor.hpp:43: invalid use of undefined type `class Game::Level'
Corridor.hpp:13: forward declaration of `class Game::Level'
Corridor.hpp:44: invalid use of undefined type `class Game::Level'
Corridor.hpp:13: forward declaration of `class Game::Level'
Corridor and Level are ...
走廊和楼层是...
// Corridor.hpp
#ifndef GAME_CORRIDOR_HPP
#define GAME_CORRIDOR_HPP
#include <Moot/Math.hpp>
//#include <Level.hpp>
#include <GameWindow.hpp>
namespace Game
{
class Level; // <-- LINE 13
class Corridor
{
static const unsigned int defaultLevelDepth = 800;
Moot::Math::Vector3D wp1, wp2, wp3, wp4;
Moot::Math::Vector2D sp1, sp2, sp3, sp4;
Level * p_level;
public:
Corridor(Moot::Math::Vector3D setFirstPoint, Moot::Math::Vector3D setSecondPoint)
{
wp1 = setFirstPoint;
wp2 = setSecondPoint;
wp3 = setFirstPoint;
wp3.z += defaultLevelDepth;
wp4 = setSecondPoint;
wp4.z += defaultLevelDepth;
}
void update() {
sp1 = p_level->getLevelCamera().convert3DVectorWithScreenAlgorithm(wp1); // <- LINE 41 etc.
sp2 = p_level->getLevelCamera().convert3DVectorWithScreenAlgorithm(wp2);
sp3 = p_level->getLevelCamera().convert3DVectorWithScreenAlgorithm(wp3);
sp4 = p_level->getLevelCamera().convert3DVectorWithScreenAlgorithm(wp4);
//p_level->getLevelCamera();
}
void draw()//const
{
Moot::Color tempColor;
windowInstance().graphics().drawQuad( sp1.x, sp1.y, tempColor,
sp2.x,sp2.y, tempColor,
sp3.x, sp3.y, tempColor,
sp4.x,sp4.y, tempColor, 1);
}
void setLevel(Level* setLevel) {
p_level = setLevel;
}
};
}
#endif
and
和
// Level.hpp
#ifndef GAME_LEVEL_HPP
#define GAME_LEVEL_HPP
#include <Moot/Forward.hpp>
#include <Moot/Window.hpp>
#include <Moot/Math.hpp>
#include <GameWindow.hpp>
#include <Camera.hpp>
#include <Corridor.hpp>
#include <Player.hpp>
#include <vector>
namespace Game
{
class Level
{
typedef Corridor* p_corridor;
typedef std::vector<p_corridor> CorridorList;
typedef CorridorList::reverse_iterator ReverseCorridorItter;
CorridorList m_map;
Camera m_camera;
Player m_player;
public:
Level()
{
m_player.setLevel(this);
// Lots of vertices being defined into m_map.
// Loop through and set camera
ReverseCorridorItter rit;
for(rit = m_map.rbegin(); rit != m_map.rend(); rit++)
(*rit)->setLevel(this);
}
~Level()
{
ReverseCorridorItter rit;
for(rit = m_map.rbegin(); rit != m_map.rend(); rit++)
delete (*rit);
m_map.clear();
}
void update()
{
// Temp delete when input and player are implimented.
if(pad[0].buttons & PAD_UP)
m_camera.updateTargetOffsets(0, -2);
if(pad[0].buttons & PAD_DOWN)
m_camera.updateTargetOffsets(0, 2);
if(pad[0].buttons & PAD_LEFT)
m_camera.updateTargetOffsets(-2, 0);
if(pad[0].buttons & PAD_RIGHT)
m_camera.updateTargetOffsets(2, 0);
m_player.update();
ReverseCorridorItter rit;
for (rit = m_map.rbegin(); rit != m_map.rend(); rit++)
(*rit)->update();
}
void draw() // const // EH!!! wtf ReverseIter isn't a member
{
m_player.draw();
ReverseCorridorItter rit;
for (rit = m_map.rbegin(); rit != m_map.rend(); rit++)
(*rit)->draw();
}
Camera& getLevelCamera() {
return m_camera;
}
};
}
#endif
The pointer is being set as far as I can tell, but when I try to access a function from Level, BOOM!
据我所知,指针正在设置,但是当我尝试从 Level 访问函数时,BOOM!
Thanks.
谢谢。
PS: The compiler is gcc 2.95.2 if that makes a difference.
PS:编译器是 gcc 2.95.2 如果这有所不同。
EDIT
编辑
Updated with complete code.
更新了完整的代码。
回答by John Dibling
You are #include
-ing Level
's complete declaration:
你是#include
-ingLevel
的完整声明:
#include <Level.hpp>
...and thenyou try to forward-declare Level
:
...然后你尝试向前声明Level
:
namespace Game
{
class Level;
Don't do this. Choose one or the other. (edit) Or at least put the forward-declaration before the #include
-ion of the complete declaration. If all you're doing in game_corridor.hpp
is setting pointers to a Level
, then a forward declare should do fine. If however you need to call functions on Level
from within the HPP file, then you'll need to #include
the complete declaration.
不要这样做。选择其中之一。(编辑) 或者至少将前向声明放在#include
完整声明的-ion之前。如果您所做的game_corridor.hpp
只是设置指向 a 的指针Level
,那么前向声明应该没问题。但是,如果您需要Level
从 HPP 文件中调用函数,则需要#include
完整的声明。
EDIT2:
编辑2:
Based on your clarifying edit to your OP, you must#include
the complete declaration of Level
, and not try to use a forward declaration.
根据您对 OP 的澄清编辑,您必须#include
完整声明Level
,而不是尝试使用前向声明。
回答by wilhelmtell
If you forward-declare Game::Level
then don't #include it. In a not-so-related note, use #include "header.hpp"
, not #include <header.hpp>
.
如果您提前声明,Game::Level
则不要 #include 它。在不太相关的注释中,使用#include "header.hpp"
,而不是#include <header.hpp>
。
Editas per your updates: Bring the definition of Game::Corridor::update()
outside the header and into an implementation file. This way the compile need not know anything about Game::Level
apart from the fact that it exists and it's a type.
根据您的更新进行编辑:将Game::Corridor::update()
标题外部的定义带入实现文件中。这样,Game::Level
除了它存在并且它是一种类型之外,编译不需要知道任何其他信息。
回答by Beta
The problem is that Corridor doesn't know what a Level is, because it can't really #include Level.hpp, because Level.hpp is what #included Corridor.hpp.
问题是Corridor 不知道Level 是什么,因为它不能真正#include Level.hpp,因为Level.hpp 就是#included Corridor.hpp。
The underlying problem is that you're trying to #include a source file. The reallyunderlying problem is that you're using #include
when you haven't separated your code into source files and header files. Here's how to split it up. (I'm assuming you're familiar with compiling source files into object files, then linking them into executables.)
潜在的问题是您正在尝试 #include 源文件。在真正的根本问题是,你使用#include
的时候你有没有代码分离为源文件和头文件。这是拆分方法。(我假设您熟悉将源文件编译成目标文件,然后将它们链接成可执行文件。)
Corridor.hpp:
走廊.hpp:
#ifndef GAME_CORRIDOR_HPP
#define GAME_CORRIDOR_HPP
#include <Moot/Math.hpp>
#include <Level.hpp>
namespace Game
{
class Level;
class Corridor
{
static const unsigned int defaultLevelDepth = 800;
Moot::Math::Vector3D wp1, wp2, wp3, wp4;
Moot::Math::Vector2D sp1, sp2, sp3, sp4;
Level * p_level;
public:
Corridor(Moot::Math::Vector3D setFirstPoint, Moot::Math::Vector3D setSecondPoint);
void update();
void draw();
void setLevel(Level* setLevel);
};
}
#endif
Corridor.cpp:
走廊.cpp:
#include "Corridor.hpp"
namespace Game
{
Corridor::Corridor(Moot::Math::Vector3D setFirstPoint, Moot::Math::Vector3D setSecondPoint)
{
wp1 = setFirstPoint;
wp2 = setSecondPoint;
wp3 = setFirstPoint;
wp3.z += defaultLevelDepth;
wp4 = setSecondPoint;
wp4.z += defaultLevelDepth;
}
void Corridor::update()
{
sp1 = p_level->getLevelCamera().convert3DVectorWithScreenAlgorithm(wp1);
sp2 = p_level->getLevelCamera().convert3DVectorWithScreenAlgorithm(wp2);
sp3 = p_level->getLevelCamera().convert3DVectorWithScreenAlgorithm(wp3);
sp4 = p_level->getLevelCamera().convert3DVectorWithScreenAlgorithm(wp4);
}
// and so on
}