2011-02-07 3 views
7

Я новичок в C/C++, я запутался о следующих:C++ включает заголовок проблемы

  1. Должен ли я поставить объявления классов в своем собственном файле заголовок, и фактической реализации в другом файл?
  2. Должен ли я помещать заголовки как <iostream> в файле example.h или в файле example.cpp?
  3. Если все классы должны использовать <iostream>, и я включаю заголовочный файл класса в заголовок другого класса, значит ли это, что я включил <iostream> дважды?
  4. Если я использую много классов STL, то стоит использовать std::?
+1

# 4 достаточно отчетливый, чтобы заслужить свой собственный вопрос. – Cameron

+0

Это достойные вопросы, но объединение всех их в одно «слишком широкое». –

ответ

8

1.Whether я должен поместить объявления классов в своем собственном файле заголовка, и фактической реализации в другом файле?

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

2.Если я должен помещать заголовки, как в файле example.h, или в файл example.cpp ?

Это зависит от того, нужны ли эти заголовки в файле example.h или только в вашем файле .cpp.

3.Если все классы нужно использовать, и я включаю файл заголовка класса, в заголовок другого класса, это значит, что я включен в два раза?

Это происходит, если вы не обернуть определения классов с помощью следующих макросов:

#ifndef FOO_HPP 
#define FOO_HPP 
class { 
... 
}; 
#endif 

5.Если я использую много классов STL, то, что это хорошая практика, чтобы использовать зЬй: :?

Я думаю, что лучше каждый раз, когда вы можете использовать std:: каждый раз вместо using namespace std. Таким образом, вы будете использовать только те пространства имен, которые вам нужны, и ваш код станет более читаемым, потому что вы избежите конфликтов пространства имен (представьте два метода, которые имеют одинаковое имя и принадлежат к двум различным пространствам имен).

Но самое главное, где вопрос номер 4 в любом случае?

+1

Удалите двойные подчеркивания перед 'FOO_HPP', и я подниму это.;) – Maxpm

+1

@Maxpm: Done :) –

1

Как правило, вы помещаете объявления классов (включая объявления членов) в файлы заголовков и определения функций-членов (методов) в исходных файлах. Заголовки обычно имеют такие имена, как *.h или *.hpp. Что касается пункта 3, вы должны включить в свои заголовки защитные ограждения, чтобы их можно было безопасно включить несколько раз в один и тот же исходный файл; то вы можете включить их везде, где они вам нужны. Я не понимаю пункт № 5: вы спрашиваете, когда использовать квалификацию пространства имен std::?

1

Для "включены дважды" проблемы, здесь общий шаблон для ваших файлов заголовков:

// _BLAHCLASS_H_ should be different for each header, otherwise things will Go Bad. 
#ifndef _BLAHCLASS_H_ 
#define _BLAHCLASS_H_ 

... rest of header ... 

#endif 
+4

Имена, начинающиеся с двух символов подчеркивания, зарезервированы для реализации компилятора; вы должны использовать другой шаблон для ваших включенных охранников (например, «BLAHCLASS_H_INCLUDED»). –

+1

Согласен с общим моментом, но что такое сделка с людьми, использующими двойные подчеркивания (я вижу это везде). Разве эти имена не зарезервированы для реализаций? (Они тоже выглядят уродливыми) –

+0

сегодня я кое-что узнал о двойных подчеркиваниях. – geofftnz

2
  1. В целом, да. Это помогает организации. Тем не менее, по небольшим проектам это может быть не так много.

  2. У меня возникли проблемы с пониманием вопроса здесь. Если вы спрашиваете, куда поставить директиву #include, файл реализации должен включать файл заголовка.

  3. Да, но использование include guards предотвращает множественные включения.

1
  1. До тех пор, пока они не шаблоны, как правило, да. Шаблоны (лучше или хуже) должны быть помещены в заголовки.
  2. Я предпочитаю, чтобы каждый из моих заголовков был «автономным», поэтому, если ему нужен какой-либо другой заголовок, он включает сам заголовок (например, если у меня есть класс, который использует std::string, заголовок для этого класса будет #include <string> Нет. С несколькими специальными исключениями необходимо писать стандартные заголовки, чтобы вы могли включать их более одного раза, не изменяя ничего (основное исключение составляет assert.h/cassert, что имеет смысл включить более чем когда-либо)
  3. Я не уверен, что вы спрашиваете. Если вы спрашиваете об использовании директивы, например using namespace std;, то это обычно (хотя, конечно, не повсеместно) нелюбовь. Использование декларации типа using std::vector; обычно считается менее проблематичным.
+0

Есть способы отделить реализацию шаблона от его объявления, но это, вероятно, выходит за рамки этого вопроса. – Maxpm

2
  1. Обычно вы должны, но для относительно небольших проектов вы можете избежать как можно большего количества файлов реализации;
  2. Если ваш заголовок использует только неполные типы из <iostream>, вы можете не включать его, но для этих типов вам потребуется forward declarations (см. When to use forward declaration?). Тем не менее, для простоты, если тип использует шаблон, я обычно включаю соответствующий заголовок;
  3. include guards гарантируют, что заголовок включен только один раз в том же translation unit;
  4. Общепринятая практика заключается в том, чтобы не поставить using namespace std в файл заголовка. Имейте в виду конфликты пространства имен;
Смежные вопросы