я должен включить заголовок, который уже включен через другие заголовки? - PullRequest
11 голосов
/ 16 октября 2010

Я только что заметил, что мои программы, использующие строковый класс, компилируются без включения заголовка <string>.Оказывается, что <iostream> включает <ios_base>, что, в свою очередь, включает <string>.

Это плохая практика, и я должен явно включать <string>?Даже если это просто пример ясности?

Можно ли предположить, что это относится не только к заголовку <string>?Возможно, это зависит от реализации и или стандартное состояние заголовка <string> должно быть включено через <ios_base> и <iostream>?Обеспечение того, чтобы любая уважаемая и широко используемая реализация всегда включала <string>, если существует вызов <iostream>.

Ответы [ 3 ]

10 голосов
/ 16 октября 2010

Вы должны явно указать любые заголовки стандартных библиотек, которые вам нужны.

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

Один случай, когда вы можете полагаться на заголовок, включаемый другим заголовком, - это если класс в одном заголовке наследуется от класса в другом. Например, <iostream> должен включать <ios_base>, поскольку классы, определенные в <iostream>, являются производными от классов, определенных в <ios_base>.

7 голосов
/ 16 октября 2010

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

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

2 голосов
/ 16 октября 2010

Если вы добавляете правильный заголовок (с «#pragma Once» или правильным #ifndef) более одного раза, это только добавляет немного больше времени к компиляции (только для открытия, анализа и удаления содержимого файла заголовка), но ничего слишком серьезного, в то время как это делает ваши файлы более легкими для компиляции, если обстоятельства изменятся (то есть перенесите их в другой проект, сделайте из них библиотеку и т. д.) Если вы действительно беспокоитесь о времени компиляции, добавьте тот же #ifndef перед включением заголовка (хотя я не рекомендую его)

т.е.

// header.h
#ifndef _HEADER_H
#define _HEADER_H
int blahblahblah(int);
#endif


// cppfile.cpp
#ifndef _HEADER_H
#include <header.h>
#endif
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...