C++ Рекурсивные заголовки для абстрактных классов

Скажем, я хочу скомпилировать что-то вроде этого:

//Prova.h:
//--------------------
#ifndef _PROVA_
#define _PROVA_

#include "Terza.h"

class Prova{
public:
 Prova();

};
#endif

а также

//Terza.h:
//--------------------
#ifndef _TERZA_
#define _TERZA_

#include "EreProva.h"

class Terza{
public:
  Terza();
};
#endif

а также

//EreProva.h:
//--------------------
#ifndef _EREPROVA_
#define _EREPROVA_

#include "Prova.h"

class EreProva : public Prova{
  public:
  EreProva();
};
#endif

который не компилирует высказывание "Prova: базовый класс не определен".

Каков наилучший способ избежать рекурсии заголовка между унаследованными классами

3 ответа

Если вам нужны циклические зависимости, значит что-то не так с вашим дизайном, и вам следует пересмотреть свой проект и попытаться удалить такие сложные и нежелательные циклические зависимости.

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

Хорошо для чтения:
Когда я могу использовать предварительную декларацию?

В этом коде:

//Prova.h:
//--------------------
#ifndef _PROVA_
#define _PROVA_

#include "Terza.h"

class Prova{
public:
 Prova();

};

Поскольку вы не используете Tezra класс в любом случае, вам не нужно #include, Возьми это. Также вам не хватает и #endif. Закрой #ifndef в этом файле с соответствующим #endif в этом файле.

Более того:

//Terza.h:
//--------------------
#ifndef _TERZA_
#define _TERZA_

#include "EreProva.h"

class Terza{
public:
  Terza();
};
#endif

#endif

Вы также не используете EreProva класс в этом файле вообще - так что возьмите #include заявление. У вас также есть дополнительный #endif в конце файла. Здесь только один #ifndef здесь, так что должен быть только один #endif, Возьми последний.

Иногда вы можете обойти проблемы такого рода, выполнив следующее: (1) попробуйте добавить директиву "#pragma Once" вверху ваших файлов, хотя это может зависеть от компилятора (я использовал ее при разработке на VC++ некоторое время назад) (2) вместо того, чтобы включать заголовочные файлы в класс, вы можете попробовать просто добавить "класс Prova" или любой другой класс, чтобы указать класс, который вы определите позже, но хотите "использовать" сейчас.

Хотя, как говорит Алс, таких конструкций лучше избегать.

Другие вопросы по тегам