简体   繁体   English

当另一个班级中包含班级时,为什么不推荐班级声明

[英]Why doesn't foward declaration of class work when class is included in another class

This compiles 这样编译

#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();
};

This doesn't 这不是

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();
};

I know that I could forward declare and use pointer for Sprite but why doesn't forward declaration works here. 我知道我可以向前声明并使用Sprite的指针,但是为什么不向前声明在这里起作用。 Doesn't "class Sprite;" 不对Sprite进行分类; tells that Sprite exists? 告诉雪碧存在吗? I'm trying #include as much classes in .cpp and avoid it in .h at any cost. 我正在尝试#include .cpp中的所有类,并不惜一切代价避免在.h中使用它。 Also classes are not including each other so there is no need to use Sprite*. 另外,类之间不包括彼此,因此不需要使用Sprite *。 I guess my understanding of what forward declaring is is wrong or something because I don't see a reason why this doesn't work. 我想我对前向声明的理解是错误的或什么原因,因为我看不出为什么这行不通。

Thanks in advance. 提前致谢。

Pretend you're the compiler. 假装您是编译器。 Without having a complete declaration of Sprite at your disposal, how is it possible to determine whether the Sprite is only one byte big, or one hundred thousand bytes big? 在没有完整的Sprite声明Sprite下,如何确定Sprite是仅一个字节还是十万个字节呢?

You don't need to know much about the class when you only need a pointer to the class (or a reference to a class, or a few other minor things); 当您只需要指向该类的指针(或对一个类的引用,或其他一些小事)时,您不需要对类有太多了解; but when you need to actually use the class, a mere forward declaration is not sufficient. 但是当您需要实际使用该类时,仅向前声明是不够的。 It's not always enough to know that " Sprite exists"; 仅仅知道“ Sprite存在”并不总是足够的。 sometimes it's necessary to know how big it is, too. 有时也有必要知道它有多大。 And without a complete declaration, that's not possible. 没有完整的声明,这是不可能的。

Forward declarations only work with references or pointers, if the type appears in the depending class declaration. 如果类型出现在从属类声明中,则前向声明仅适用于引用或指针。

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();
};

Care to include the Sprite.h file in your implementation, and initialize the member in your constructor implementation ideally (a reference would require that strictly). 注意将Sprite.h文件包含在您的实现中,并在理想的情况下在构造函数实现中初始化该成员(严格按引用要求)。

Sprite can't be incomplete type here, because the size and layout of it must be known as the non-static member of class GameObject . Sprite不能是不完整的类型 ,因为必须将其大小和布局称为GameObject类的非静态成员。

(Note the 3rd one) (注意第三个)

Any of the following contexts requires class T to be complete: 以下任何上下文均要求类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*. 

On the other hand, if you declare it as pointer or reference, incomplete type is fine and forward declaration will be allowed. 另一方面,如果将其声明为指针或引用,则可以使用不完整的类型,并允许进行正向声明。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM