当班级被包含在另一个班级

时间:2016-07-26 02:13:31

标签: c++ class include declaration forward-declaration

这个编译

#include "Sprite.h"

class GameObject
{
  public:
      int x, y, w, h;
      Sprite sprite;
  public:
    GameObject();
    GameObject(int _x, int _y, int _w, int _h);
    virtual ~GameObject();
};

这不是

class Sprite;

class GameObject
{
  public:
      int x, y, w, h;
      Sprite sprite;
  public:
    GameObject();
    GameObject(int _x, int _y, int _w, int _h);
    virtual ~GameObject();
};

我知道我可以转发声明并使用Sprite的指针,但为什么不转发声明在这里工作。 没有"类Sprite;"告诉Sprite存在? 我在.cpp中尝试#include尽可能多的类,并且不惜任何代价在.h中避免它。 类也不相互包含,因此不需要使用Sprite *。 我想我对前方声明的理解是错误的,或者是因为我没有看到为什么这样做不起作用的理由。

提前致谢。

3 个答案:

答案 0 :(得分:3)

假装你是编译器。如果没有完整的Sprite声明,如何确定Sprite只有一个字节大,或十万字节大?

当你只需要一个指向类的指针(或对类的引用,或者其他一些小事)时,你不需要了解很多关于类的知识;但是当你需要实际使用这个类时,仅仅前向声明是不够的。并不总是知道" Sprite存在&#34 ;;有时也需要知道它有多大。如果没有完整的声明,这是不可能的。

答案 1 :(得分:2)

如果类型出现在依赖类声明中,则前向声明仅适用于引用或指针。

class Sprite;

class GameObject
{
  public:
      int x, y, w, h;
      Sprite* sprite; // <<<<
  // or Sprite& sprite;
  public:
    GameObject();
    GameObject(int _x, int _y, int _w, int _h);
    virtual ~GameObject();
};

注意在您的实现中包含Sprite.h文件,并在理想情况下初始化构造函数实现中的成员(严格要求引用)。

答案 2 :(得分:1)

Sprite不能在此incomplete type,因为它的大小和布局必须被称为类GameObject的非静态成员。

(注意第3个)

  

以下任何一种情况都要求完成课程T

definition or function call to a function with return type T or argument type T;
definition of an object of type T;
declaration of a non-static class data member of type T;
new-expression for an object of type T or an array whose element type is T;
lvalue-to-rvalue conversion applied to a glvalue of type T;
an implicit or explicit conversion to type T;
a standard conversion, dynamic_cast, or static_cast to type T* or T&, except when converting from the null pointer constant or from a pointer to void;
class member access operator applied to an expression of type T;
typeid, sizeof, or alignof operator applied to type T;
arithmetic operator applied to a pointer to T;
definition of a class with base class T;
assignment to an lvalue of type T;
a catch-clause for an exception of type T, T&, or T*.

另一方面,如果您将其声明为指针或引用,则不完整类型就可以了,并且允许前向声明。