2016-12-29 4 views
0

У меня есть заголовочный файл, называемый Person.h:Заголовок спутанность порядок включения

class Person 
{ 
    public: 
     Person(); 
    private: 
     std::string name; 
}; 

Реализация находится в файле с именем Person.cpp:

#include <string> 
#include "Person.h" 

Person::Person() 
{ 
    name = "foo"; 
} 

Я привык, чтобы избежать вложенной включая файлы, поэтому я #include, заголовок <string>, прежде чем включать заголовок класса в исходный файл класса.

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

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

Итак, мой вопрос: почему он не компилируется без включения строкового заголовка в файл заголовка? Поскольку заголовочный файл «скопирован» в исходный файл после#include <string>, я ожидаю, что он будет компилироваться просто отлично.

+0

Хорошо, давайте рассмотрим ваши основные предположения. Почему именно вы «* использовали, чтобы избежать [in] вложенных файлов include *» (что я подразумеваю, включая заголовки из других заголовков)? – NPE

+0

@NPE пожалуйста, ответ на мой вопрос. как я писал, он работает в C, я хочу знать, почему это не должно быть на C++, даже если я нашел в Интернете, что он должен быть – Luca

+3

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

ответ

1

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

3

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

Переместите включение <string.h> в файл заголовка, чтобы устранить эту проблему.

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

[должен видеть декларации вперед] то же самое в C. Но он должен получить их из файла заголовка, включенного ранее в файл cpp.

Оказывается, что есть и другие места, с которого вы включаете Person.h заголовочный файл, в дополнение к Person.cpp. Это то, что вызывает ошибку.

+0

да, я знаю, что ему нужно видеть форвардные объявления. То же самое в C. Но он должен получить их из файла заголовка, включенного ранее в файл cpp. – Luca

+3

@Luca Похоже, что есть другие места, из которых вы включаете заголовок 'Person.h' (при условии, что вы не передаете заголовок компилятору как одну из единиц перевода, потому что это было бы ошибкой). – dasblinkenlight

+0

спасибо! Ваш только соответствующий ответ на мой вопрос. Это действительно так, я также включил заголовок в main.cpp, следовательно, ошибку. Так что это была просто глупая моя ошибка, включение работает так же, как и в C. Если вы сделайте этот комментарий ответом, я могу отметить его как правильно. Спасибо – Luca

0

Вы хотите использовать как стандартные файлы заголовков и все остальные делают, include guards

#ifndef PERSON_H 
#define PERSON_H 

/// your header file 

#endif // PERSON_H 
+0

Я знаю это. Это просто простой пример. защита заголовков. Но почему это не работает? – Luca