Gar*_*ckW 2 c++ inheritance forward-declaration
所以我试图让班级"Herder"继承"Mob"班.但我收到的编译器错误如下:
error: invalid use of incomplete type 'struct Mob'
error: forward declaration of 'struct Mob'
这就是Herder.h的样子:
#ifndef HERDER_H_INCLUDED
#define HERDER_H_INCLUDED
#include <SFML/Graphics.hpp>
#include <cstdlib>
#include "Level.h"
#include "Mob.h"
class Mob;
class Herder : public Mob
{
public:
    //Member functions.
    Herder(Level* level, int x, int y);
    void virtual GameCycle(sf::RenderWindow* App);
    void virtual Die();
    void Roar();
protected:
    float m_RoarCountdown;
    float m_RoarTime;
    float m_Speed;
    bool m_Roaring;
};
#endif // HERDER_H_INCLUDED
确定它必须class Mob;是导致这种情况,我将其删除,但后来我得到以下错误,引用花括号打开的行:
error: expected class-name before '{' token
这实际上是我最初添加前向声明的原因 - 我原以为编译器没有认识Mob到class Herder : public Mob,所以我想我会转发声明.
我不认为这是一个周期性依赖的情况,正如我通过谷歌发现的某些情况一样 - "Mob.h"与Herder课程无关.
我已经尝试#include "Mob.h"完全删除并坚持使用前向声明,但这也不起作用 - 我只得到一个错误:
error: invalid use of incomplete type 'struct Mob'
这令人困惑.我以前成功地让类继承了,这段代码在我以前成功尝试的所有相关方面看起来都很相似.
编辑:这是内容 Mob.h
#ifndef MOB_H_INCLUDED
#define MOB_H_INCLUDED
#include <SFML/Graphics.hpp>
#include <cstdlib>
#include "Level.h"
class Level;
class Mob
{
public:
    //Member functions.
    Mob(Level* level, int x, int y);
    float GetX();
    float GetY();
    void SetColor(sf::Color color);
    void virtual GameCycle(sf::RenderWindow* App) = 0;
    void virtual Die() = 0;
    void Draw(sf::RenderWindow* App);
protected:
    float m_X;
    float m_Y;
    bool m_Moving;
    int m_Health;
    sf::Sprite m_Sprite;
    Level* pLevel;
};
#endif // MOB_H_INCLUDED
编辑:以下是"Level.h"文件的内容.请注意,Baby是一个子类Mob中多以同样的方式Herder; 两者都遇到同样的错误.
#ifndef LEVEL_H_INCLUDED
#define LEVEL_H_INCLUDED
#include <SFML/Graphics.hpp>
#include <cstdlib>
#include "Tile.h"
#include "Herder.h"
#include "Baby.h"
class Tile;
class Herder;
class Baby;
/// LEVEL
/// This is the collection of all data regarding a level, including layout, objects, mobs, and story elements.
///
class Level
{
public:
    //Constructor
    Level(int height, int width, std::string name);
    //For obtaining positional data
    int GetHeight();
    int GetWidth();
    std::string GetName();
    sf::Image GetTileImage(int image);
    sf::Image GetMobImage(int image);
    std::vector< std::vector<Tile> >& GetGrid();
    void NewHerder(int x, int y);
    void NewBaby(int x, int y);
    void GameCycle(sf::RenderWindow* App);
    void GraphicsCycle(sf::RenderWindow* App);
private:
    //Size
    int m_Height;
    int m_Width;
    //Spatial coords
    std::string m_Name;
    //The grid of tiles.
    std::vector< std::vector<Tile> > m_Grid;
    //A vector of the images to be used for tiles.
    std::vector<sf::Image> m_TileImages;
    //A vector of the images to be used for tiles.
    std::vector<sf::Image> m_MobImages;
    //The herders
    std::vector<Herder> m_Herders;
    //The babies
    std::vector<Baby> m_Babies;
};
#endif // LEVEL_H_INCLUDED
编辑:先发制人,以下是内容Tile.h:
#ifndef TILE_H_INCLUDED
#define TILE_H_INCLUDED
#include <SFML/Graphics.hpp>
#include <cstdlib>
#include "Level.h"
class Level;
/// TILE
/// This is the basic environmental unit in the game
///
class Tile
{
public:
    //Constructor
    Tile(int col, int row, int size, int type, Level* level);
    //For obtaining positional data
    int GetX();
    int GetY();
    int GetRow();
    int GetCol();
    //For obtaining type data
    int GetType();
    //For obtaining string type data
    std::string GetStringType();
    //For changing type data
    void SetType(int type);
    void SetStringType(std::string character);
    //For activities that regularly take place
    void GameCycle();
    //Draws the tile.
    void Draw(sf::RenderWindow* App);
private:
    //The level this tile belongs to.
    Level* m_Level;
    //Size (it's a square!)
    int m_Size;
    //Spatial coords
    int m_X;
    int m_Y;
    //Grid coords
    int m_Row;
    int m_Col;
    //Type
    int m_Type;
    //Visual data
    sf::Sprite m_Tile;
};
#endif // TILE_H_INCLUDED
它是循环依赖(Herder.h包括Level.h,包括Herder.h等).
在Herder.h中,只需将其替换为:
#include "Level.h"
用:
class Level;
并在Mob.h中执行相同的操作
一般规则是尽可能少地包含头文件(即只包含您需要的头文件).如果你可以使用前向声明,例如,那么使用它而不是完整的包含.