包含的循环类依赖性

时间:2012-08-12 18:40:13

标签: c++ class

这基本上是我的班级布局:

GameDriver.h:

#ifndef GAMEDRIVER_H
#define GAMEDRIVER_H
#include "CameraSystem.h"

class CameraSystem; //Forward declaration

class GameDriver {
    //Stuff
};

#endif

CameraSystem.h:

#ifndef CAMERASYSTEM_H
#define CAMERASYSTEM_H
#include "Tickable.h"

class GameDriver;
class CameraSystem: public Tickable { //Complains here
    //Stuff
};

#endif

Tickable.h:

#ifndef TICKABLE_H
#define TICKABLE_H
#include "GameDriver.h"
class GameDriver;
class Tickable {
    //Stuff
};

#endif

这是我得到的错误:

CameraSystem.h:9 error: expected class-name before '{' token

转发声明Tickable也不起作用。有帮助吗?提前谢谢。

5 个答案:

答案 0 :(得分:3)

如果你转发声明一个类,你不应该包含类'标题。

#include "CameraSystem.h" // DO NOT INCLUDE THIS

class CameraSystem; //Forward declaration

class GameDriver {
    //Stuff
};

答案 1 :(得分:1)

好的,我在这里看到两个问题。

首先:您的前瞻性声明无用。你正在写(使用GameDriver.h:作为一个例子):

#include "CameraSystem.h"

class CameraSystem; //Forward declaration

class GameDriver {
    //Stuff
};

这里CameraSystem已经知道包含CameraSystem.h,因此前向声明是无意义的。你打算写的是:

class CameraSystem; //Forward declaration

class GameDriver {
    //Stuff
};

第二:你真的需要一个前瞻性声明,你不能使用它,因为你不能从前面声明的类派生出来:

#include "Tickable.h"

class CameraSystem: public Tickable { //Complains here
    //Stuff
};

请注意,如果您未直接将前向声明的类用作类成员,则前向声明仅 。然后,您将被限制为指向前向声明的类的指针或引用。原因是编译器不知道类的内存布局,除非它完全已知(即通过包括头文件)。例如:

class CameraSystem;
class GameDriver {
  CameraSystem m_cameraSystem;
};

工作。然而,

class CameraSystem;
class GameDriver {
  CameraSystem *m_cameraSystem;
  CameraSystem& m_otherCameraSystem;
};

意愿。当然,您仍需要在* .cpp文件中包含正确的头文件。

答案 2 :(得分:0)

您无法解决此类循环依赖项。但是,你已经得到了解决方案(部分):

即。而不是包括标题,只需使用前向声明。如果你这样做,那就不应该有任何问题。但是,尝试将程序分组为逻辑元素/组,并且只有在需要时才添加交叉引用(例如,游戏必须知道并访问相机,但相机不应该以游戏系统的形式访问整)。

答案 3 :(得分:0)

您不能从尚未声明的类继承。

预处理Tickable.h为您提供:

class GameDriver;
class CameraSystem: public Tickable { //Complains here
    //Stuff
};

class CameraSystem; //Forward declaration

class GameDriver {
    //Stuff
};

class GameDriver;
class Tickable {
    //Stuff
};

当你从它继承时,看看Tickable甚至没有被声明为前向声明?

答案 4 :(得分:-2)

尝试在每个头文件的最开头添加#pragma once

你应该以某种方式告诉编译器只放一次。这是一种方式。另一种方法是使用#ifndef X#define X

如果这不能解决它,试着消除循环依赖 - 它似乎不会发生......