为什么 class 声明顺序仍然对原型制作很重要?

Why class declaration ordering still matters with prototyping?

我一直在努力解决我的代码中的“字段 "player" 类型不完整”错误。我的 class "game_session" 包含一个 "player" 并且我声明了它们在同一个头文件中,如下所示:

#ifndef HEADER_H
#define HEADER_H

#include <iostream>
#include <vector>

using std::vector;

class Player;
class GameSession;

class GameSession{
 private:
  ...
  Player player;
 public:
  GameSession();
  ~GameSession();
  ...
};

class Player {
 public:
  Player( int maxdim );
  ~Player();
  ...
};  

以上代码无法编译,因为 GameSession 找不到 Player class 的声明。当我切换两个 classes 时它起作用了,如下所示:

#ifndef HEADER_H
#define HEADER_H

#include <iostream>
#include <vector>

using std::vector;

class Player {
 public:
  Player( int maxdim );
  ~Player();
  ...
};

class GameSession{
 private:
  ...
  Player player;
 public:
  GameSession();
  ~GameSession();
  ...
};

我不再需要原型了。我的问题是,为什么原型设计不能防止由于缺少有序声明而导致的错误?此外,当有很多 classes 和依赖项时,将来如何避免这种情况?

弹客

(对于那些想知道的人,我在 class 实现中使用了一个初始化列表来处理 Player 没有默认构造函数的事实)

要完全声明 GameSession,编译器需要计算出其所有成员的大小。所以既然有一个 Player 成员,它需要 Player.

的完整声明

如果 player 成员改为指针或引用,则编译器不需要完整声明 Player 因为编译器已经知道指针或引用的大小,而不管class 是什么类型的点或指代。

据我所知,在使用作为 class 实例的成员时,没有任何神奇的方法可以解决具有完整声明的要求。所以你要选择你喜欢的技术和相应的要求。