Как возвращающийся новичок на C++, я пытаюсь сортировать методологию #include.Где должно быть указано #include?
Я следую определенному набору руководств, которые я подробно описываю ниже в следующем примере. Пока это сработало для меня (весь проект держит компиляцию :)), но я беспокоюсь, что в будущем я могу столкнуться с проблемами, поэтому мои вопросы - - это правильная методология? Есть ли лучший? Какова основная логика, которая объясняет это?
Рассмотрим следующий пример:
Father.h
#pragma once
class Father
{
// Some implementation
};
ClassA.h
#pragma once
#include "Father.h"
#include "StructC.h"
class ClassB;
class ClassA : public Father
{
StructC struct_c_obj;
ClassB class_b_obj;
// Some implementation
};
ClassA.cpp
#include "Father.h"
#include "ClassB.h"
#include "StructC.h"
// Some implementation
ClassB.h и ClassB.cpp
Класс без включает
StructC.h
struct StructC {
// Some implementation
};
Я следую этим правилам:
- Все * .h возглавляет
#pragma once
декларация - Если ClassA наследует от класса Отца, он должен включить его в обеих * .h и * .cpp файл
- Если ClassA использует ClassB (и имеет переменный ClassB объявленные в области видимости класса), он имеет
class ClassB;
decleration в ClassA.h и#include "ClassB.h"
в ClassA.cpp - Если ClassA использует StructC (и имеет StructC переменную, объявленную в области видимости класса), он должен включить его в обоих ClassA.h и ClassA.cpp
- If ClassA использует ClassD или StructE, но только в файле ClassA.cpp, тогда он должен включать их только там
Это, вероятно, неуклюжий набор руководств с небольшим пониманием основной логики, поэтому я, вероятно, собираюсь получить некоторый гнев ... Принесите его, я am пытается узнать здесь ...:)
ОБНОВЛЕНИЕ:
- Как некоторые уже написано ниже, у меня есть ошибка в примере - вы можете использовать вышеописанную декларацию ClassB в ClassA только если ClassA имеет указатель или ссылку на ClassB а не если он имеет простой элемент данных ClassB.
У меня есть два вопроса относительно вашего ответа: 1) почему мы должны предпочесть декларации вперед? 2) Я пытаюсь понять, почему бы не использовать #pragma, почему важно, чтобы это не было в стандарте? – Delashmate
1) Потому что он уменьшает связь (любой файл, который содержит заголовок, прямо или косвенно, должен быть перекомпилирован при изменении заголовка) 2) Поскольку вам может понадобиться затем портировать ваш код другому компилятору – icecrime
+1. Это хороший ответ. Я бы добавил, что порядок включает в себя: 'ClassA.h' сначала, затем любые' ClassB.h' или другие ваши собственные, затем заголовки Boost или другие заголовки библиотек и, наконец, стандартные заголовки библиотек ('string', 'vector' и т. д.). Следуя этому порядку, вы гарантируете, что ваши собственные заголовки самодостаточны. –