#include и возможные циклические ссылки - PullRequest
3 голосов
/ 24 ноября 2011

Так что моя последняя ошибка начинает очень сильно меня беспокоить, и я осмотрел интернет, и лучшее решение, которое я нашел, - это то, что у меня есть циклическая ошибка #include, но я не уверен, что точно вызывая это. Моя структура включения выглядит следующим образом:

Player.h -includes-> Pawn.h -includes-> Piece.h -includes-> Player.h

Я имею в виду, мне кажется очевидным, что это циклическая проблема включения, но я не знаю, как ее преодолеть. Чтобы усложнить ситуацию, класс Pawn расширяет Piece, а Piece имеет boost::weak_ptr обратно к Player. Причина, по которой мои включения выглядят так, заключается в том, что Player имеет vector из Pawn s (и других Piece s), но Pawn также должен вызывать некоторые из Player методов, поэтому я дал Базовый класс Piece от weak_ptr до Player для этого.

Каким образом я могу разработать это лучше, чтобы у меня не было циклического включения?

Ответы [ 3 ]

3 голосов
/ 24 ноября 2011

Вы можете обойти это, используя предварительные объявления;на самом деле, вы должны предпочесть, чтобы они включали заголовки в большинстве случаев.

Когда заголовку не нужно знать о любых деталях реализации другого класса, вы можете использовать форварддекларация для него, вместо включения полного определения класса.По сути, это говорит компилятору: «Есть класс с этим именем», но больше ничего.

// This is a forward declaration. It tells the compiler that there is a 
// class named Player, but it doesn't know the size of Player or what functions
// it has.
class Player; 

struct Piece {
   // This is just a pointer to player. It doesn't need to know any details about
   // Player, it just needs to know that Player is a valid type.
   boost::weak_ptr<Player> player;
};

Как правило, если файл передает только указатель или ссылку на определенный тип, этот тип долженбыть вперед объявлен.Однако, если он попытается фактически использовать объект этого типа, это приведет к ошибке компилятора.В этом случае вам необходимо включить соответствующий заголовок.

В большинстве случаев вы захотите включить заголовки для любых объявленных вперед классов в исходном файле, чтобы вы могли фактически использовать объекты, на которые указывают.

1 голос
/ 24 ноября 2011

Во всех ваших заголовочных файлах используйте Заголовки , которые выглядят так:

#ifndef PLAYER_H
#define PLAYER_H

//contents of your header file go here

#endif
0 голосов
/ 24 ноября 2011
Перемещение

включает (если возможно) в файл .cpp. если у вас все еще есть циклы, распакуйте материал, который наиболее распространен в отдельный файл. в вашем случае включение Piece.h для Player.h кажется проблематичным (только догадка).

...