当 class 包含在另一个 class 中时,为什么 class 的转发声明不起作用
Why doesn't foward declaration of class work when class is included in another class
这样编译
#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 转发声明和使用指针,但为什么转发声明在这里不起作用。
"class Sprite;" 不是说 Sprite 存在吗?
我在 .cpp 中尽可能多地尝试 #include 类 并不惜一切代价在 .h 中避免它。
此外 类 不相互包含,因此无需使用 Sprite*。
我想我对前向声明的理解是错误的,因为我看不出这是行不通的原因。
提前致谢。
假装你是编译器。如果没有完整的 Sprite
声明供您使用,如何确定 Sprite
是只有一个字节大还是十万字节大?
当您只需要指向 class 的指针(或对 class 的引用或其他一些次要事物);但是当你需要实际使用 class 时,仅仅前向声明是不够的。知道“Sprite
存在”并不总是足够的;有时也有必要知道它有多大。没有完整的声明,这是不可能的。
如果类型出现在依赖 class 声明中,则前向声明仅适用于引用或指针。
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
文件,并理想地在您的构造函数实现中初始化成员(引用将严格要求)。
Sprite
这里不能是incomplete type,因为它的大小和布局必须知道是classGameObject
的非静态成员。
(注意第三个)
Any of the following contexts requires class T
to be complete:
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*.
另一方面,如果您将其声明为指针或引用,不完整的类型是可以的,并且允许向前声明。
这样编译
#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 转发声明和使用指针,但为什么转发声明在这里不起作用。 "class Sprite;" 不是说 Sprite 存在吗? 我在 .cpp 中尽可能多地尝试 #include 类 并不惜一切代价在 .h 中避免它。 此外 类 不相互包含,因此无需使用 Sprite*。 我想我对前向声明的理解是错误的,因为我看不出这是行不通的原因。
提前致谢。
假装你是编译器。如果没有完整的 Sprite
声明供您使用,如何确定 Sprite
是只有一个字节大还是十万字节大?
当您只需要指向 class 的指针(或对 class 的引用或其他一些次要事物);但是当你需要实际使用 class 时,仅仅前向声明是不够的。知道“Sprite
存在”并不总是足够的;有时也有必要知道它有多大。没有完整的声明,这是不可能的。
如果类型出现在依赖 class 声明中,则前向声明仅适用于引用或指针。
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
文件,并理想地在您的构造函数实现中初始化成员(引用将严格要求)。
Sprite
这里不能是incomplete type,因为它的大小和布局必须知道是classGameObject
的非静态成员。
(注意第三个)
Any of the following contexts requires class
T
to be complete: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*.
另一方面,如果您将其声明为指针或引用,不完整的类型是可以的,并且允许向前声明。