Бесконечные циклы включения
Возможный дубликат:
Циклы файла заголовка C
Оригинальный вопрос:
У меня всегда были проблемы с пониманием, почему следующее дает ошибки:
something.h
#ifndef SOMETHING_H
#define SOMETHING_H
#include "somethingelse.h"
#endif
somethingelse.h
#ifndef SOMETHINGELSE_H
#define SOMETHINGELSE_H
#include "something.h"
#endif
Почему это дает ошибки?
1) SOMETHING_H не определено
2) SOMETHING_H становится определенным, что-то другое.
3) SOMETHINGELSE_H не определен, становится определенным и что-то.h включается
4) SOMETHING_H определен, перейдите к #endif, это должно быть конец?
РЕДАКТИРОВАТЬ:
Оказывается, это не дает никаких ошибок вообще. Однако следующее делает:
something.h
#pragma once
#include "somethingelse.h"
class something {
int y;
somethingelse b;
};
somethingelse.h
#pragma once
#include "something.h"
class somethingelse {
something b;
int x;
};
И это логично, потому что класс "что-то" еще не определен, когда "что-то еще" нуждается в экземпляре этого класса.
Задача решается путем прямого определения:
something.h
#pragma once
class somethingelse;
class something {
int y;
somethingelse* pB; //note the pointer. Correct me if I'm wrong but I think it cannot be an object because the class is only declared, not defined.
};
в.cpp вы можете включить "somethingelse.h" и создать экземпляры класса.
2 ответа
Ваше описание в точности верно, за исключением того, что ошибки нет вообще. добавлять pragma message("Some text")
(предполагая Visual Studio) в разных местах, чтобы проследить поток.
Как уже отмечали другие авторы, ваши заголовочные файлы, скорее всего, содержат классы, которые взаимно требуют друг друга определения, и это является причиной проблемы. Такая проблема обычно решается
- Использование прямых ссылок, где это возможно
- перемещение
#include
s в файлы CPP, где это возможно
Именно так и происходит.
Это называется защитой включения и используется для предотвращения бесконечно рекурсивных включений.