Должен '#include' и операторы 'использования' быть повторенными и в файлах заголовка и в реализации (C++)?

Я довольно плохо знаком с C++, но мое понимание - то, что #include оператор по существу просто выведет содержание #included файла в местоположение того оператора. Это означает, что, если у меня есть много '#include' и операторы 'использования' в моем заголовочном файле, мой файл реализации может просто #include заголовочный файл, и компилятор не будет возражать, если я не повторю другие операторы.

Что относительно людей, хотя?

Мое основное беспокойство - то, что, если я не повторяю '#include', 'использование' и также 'определение типа' (теперь, когда я думаю о нем) операторы, это устраняет ту информацию из файла, в котором это используется, который мог привести к беспорядку.

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

Пример следует:

ОБНОВЛЕНИЕ: мои прототипы функции для 'Единицы' имеют строку, ostream и StringSet среди их типов возврата и параметров - я ничего не включаю в свой заголовочный файл, который используется только в файле реализации.

//Unit.h

#include <string>
#include <ostream>
#include "StringSet.h"

using std::string;
using std::ostream;

class Unit {

public:
    //public members with string, ostream and StringSet
    //in their return values/parameter lists
private:
    //private members
    //unrelated side-question: should private members
    //even be included in the header file?
} ;


//Unit.cpp

#include "Unit.h"

//The following are all redundant from a compiler perspective:
#include <string>
#include <ostream>
#include "StringSet.h"

using std::string;
using std::ostream;

//implementation goes here
6
задан Deduplicator 23 January 2015 в 23:33
поделиться

4 ответа

Директива использования ( using namespace std; ) не должна находиться в заголовке, если она не содержится в функции. Это плохая практика. Маловероятно, что каждому пользователю вашего заголовка нужен неквалифицированный поиск всего в данном пространстве имен; включение несвязанных заголовков может привести к неожиданной неоднозначности и сбоям компиляции. Лично я избегаю использования директивы using внутри функций по тем же соображениям, но обычно это считается менее вредным.

Псевдоним типа (либо через typedef std :: string string; или using string = std :: string; ) следует использовать осторожно. Определения типов имеют значение, поэтому никогда не следует объявлять его повторно. Например, это ошибка:

typedef int   myint;
typedef float myint;

из-за конфликтующих типов.

A объявление-использования ( using std :: string; или using std :: memcpy; ) делает символ доступным для неквалифицированного имени поиск . Это чрезвычайно полезно при получении зависимого от аргумента поиска правильного, что обычно не имеет значения, если вы не пишете библиотеку. Рекомендации различаются в зависимости от того, вводите ли вы тип или функцию. Подумайте о using-декларации с типами так же, как псевдоним типа : нет смысла иметь несколько определений под одним и тем же именем. С функциями все, что вы на самом деле делаете, - это расширяете разрешение перегрузки, чтобы включить еще несколько вещей (хотя обычно в этом нет необходимости).

// Finding multiple operator<< functions makes sense
using std::operator<<;
using mylib::operator<<;

// Finding multiple string classes does not make sense
using std::string;
using mylib::string;

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

6
ответ дан 10 December 2019 в 02:44
поделиться

Как сказал Трэвис, у вас не должно быть using операторов в файле заголовка, потому что это означает, что они будут включены во весь перевод единицы, которые включают этот файл заголовка, что может вызвать запутанные проблемы.

Если мне нужны только функции из файла заголовка в файле cpp, я включаю их только в этот файл cpp. Это хорошая практика для больших проектов, потому что это означает меньше работы для компилятора. Кроме того, везде, где это возможно, я использую форвардные объявления в заголовках вместо включения (и снова включаю заголовки в файл cpp).

0
ответ дан 10 December 2019 в 02:44
поделиться

Сведите файлы заголовков к минимуму. Это означает как можно меньше включений. файл .cpp обычно включает соответствующий заголовок, а также любые другие заголовки, необходимые для реализации.

0
ответ дан 10 December 2019 в 02:44
поделиться

Считается плохим тоном иметь Использование оператора в файле заголовка вообще, если вы намеренно не дублируете символ в другое пространство имен. Это нормально для использования в файле cpp.

Каждый typedef должен существовать только один раз в вашей кодовой базе. Это должно быть в файле заголовка, если его нужно использовать в нескольких файлах cpp / h. Их дублирование вызовет у вас много горя.

Заголовочный файл должен содержать все необходимые ему операторы #include и никакие другие. Если упоминаются только указатели на класс, используйте предварительное объявление вместо включения заголовка. Любые другие включения, которые требуются только внутри файла cpp, должны идти туда. Повторение включения из заголовка - это нормально, но не обязательно. Это просто выбор стиля.

0
ответ дан 10 December 2019 в 02:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: