【问题标题】:Why doesn't foward declaration of class work when class is included in another class当类包含在另一个类中时,为什么不转发类的声明
【发布时间】:2016-07-26 02:13:30
【问题描述】:

这样编译

#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 转发声明和使用指针,但是为什么转发声明在这里不起作用。 不是“类雪碧”;告诉雪碧存在? 我正在尝试#include .cpp 中的尽可能多的类,并不惜一切代价避免在 .h 中使用它。 此外,类不包括彼此,因此无需使用 Sprite*。 我想我对前向声明的理解是错误的或其他什么,因为我看不出这不起作用的原因。

提前致谢。

【问题讨论】:

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


    【解决方案1】:

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

    当您只需要一个指向类的指针(或对类的引用,或其他一些小事)时,您不需要对类了解太多;但是当您需要实际使用该类时,仅仅前向声明是不够的。知道“Sprite 存在”并不总是足够的;有时也有必要知道它有多大。如果没有完整的声明,这是不可能的。

    【讨论】:

    • 所以它与指针一起工作的原因是因为指针唯一需要知道的是内存地址的大小总是相同的?
    • 酷,总结一下,我也学了点指针,谢谢大佬
    【解决方案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 文件,并在理想情况下在构造函数实现中初始化该成员(引用将严格要求)。

    【讨论】:

      【解决方案3】:

      Sprite这里不能是incomplete type,因为它的大小和布局必须知道类GameObject的非静态成员。

      (注意第三个)

      以下任何情况都需要类 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*.
      

      另一方面,如果你将它声明为指针或引用,不完整的类型是可以的,并且允许前向声明。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-04-26
        • 1970-01-01
        • 1970-01-01
        • 2013-05-27
        • 1970-01-01
        • 2020-12-03
        • 1970-01-01
        • 2010-10-15
        相关资源
        最近更新 更多