2011-01-21 2 views
1

http://www.learncpp.com/cpp-tutorial/19-header-files/заголовков файлов в сравнении с упреждающее объявление

Он упоминает следующее в качестве другого решения «вперед декларации»:

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

Но, не может ли это быть сделано с «форвардной декларацией»? Так как мы определяем функцию int add(int x, int y), например, в «add.cpp», и использовать эту функцию в «main.cpp», набрав:

Int надстройки (целое х, Int у);

? Спасибо.

+1

В конце концов, это то, что делает прекомпилятор, включая заголовочный файл в исходном файле. – stefaanv

+1

Я считаю, что ваш фрагмент кода не должен показывать вопросительный знак & thank;) – IsaacS

ответ

4

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

  1. Вы только что скопировали одно и то же объявление во множество разных файлов. Если вы когда-либо меняете подпись функции, вам нужно изменить каждое место, в которое вы вложили свою декларацию вперед.
  2. Само декларируемое само по себе само по себе не говорит вам, в каком файле определяется фактическая функция. Если вы используете разумный метод организации ваших заголовочных файлов и исходных файлов (например, объявлена ​​каждая функция, определенная в файле .cpp в .h-файле с тем же именем), то место, в котором определена функция, подразумевается местом, которое оно объявлено.
  3. Ваш код будет менее читабельным для других программистов, которые очень привыкли использовать заголовочные файлы для всего (по уважительной причине), даже если все, что вам нужно из заголовка, является одной конкретной функцией, и вы можете легко переслать-объявить ее самостоятельно ,
1

I C и C++ по существу помещают все прямые и внешние объявления в заголовок. Затем это обеспечивает удобный способ включения их в различные исходные файлы без необходимости их вручную включать.

В вашем случае, если вы добавили определенный в add.cpp, вы можете просто предоставить внешнюю декларацию в main.cpp, и все будет круто. Файл заголовка поможет вам, когда у вас есть большое количество файлов, которые требуют добавления объявленных и не хотят делать это для каждого из них.

+0

Когда вы говорите: «Заголовочный файл там, чтобы помочь вам, когда у вас есть большое количество файлов, которые требуют добавления объявленных и не хотят сделайте это для каждого ». Когда мы хотим использовать« файл заголовка », не следует ли объявлять его во ВСЕХ файлах, которые нуждаются в функции« добавить »? Благодарю. – Simplicity

0
int add(int x, int y); // forward declaration using function prototype 

Можете ли вы объяснить, "опережающее объявление" еще дальше? В чем проблема, если мы используем его в функции main()?

Это то же самое, что и #include"add.h". Если вы знаете, препроцессор расширяет файл, который вы указываете в #include, в .cpp-файле, где вы пишете директиву #include. Это означает, что если вы напишете #include"add.h", вы получите то же самое, это как если бы вы делали «форвардную декларацию».

Я предполагаю, что add.h имеет следующую строку:

int add(int x, int y); 

What are forward declarations in C++?

2

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

У вас может быть библиотека функций, например. matrix.c для матричных операций. Без файлов заголовков вам нужно было бы копия. Передовые декларации для всех matrix.c функционируют во всех других исходных файлах. Вам также необходимо будет обновлять все эти копии с любыми изменениями до matrix.c.

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

Имея декларации в одном файле, обычно matrix.h, который будет использоваться везде, удаляет все эти проблемы.

2

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

В общем, заголовочный файл определяет интерфейс для кода.

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

Решение в виде заголовка гораздо удобнее обслуживать (меньше подвержено ошибкам) ​​и значительно упростить определение того, какой код используется.

+0

Можете ли вы просто объяснить это более подробно? Lso, подумайте, что произойдет, если функция требует определенного пользовательского типа. Собираетесь ли вы направить это объявление тоже? Этот тип может регулярно изменять его реализацию (сохраняя его публичный интерфейс одинаковым), что приведет к в том, что нужно регулярно менять все передовые декларации ».? Благодарю. – Simplicity

+1

Представьте себе функцию int foo (someClass arg); Чтобы вызвать foo(), вам нужно объявить foo() и someClass. someClass может быть большим, может иметь только несколько общедоступных методов, но может иметь много частных/защищенных методов и членов. Общественные части не должны меняться, но другие части могут. Метод файла заголовка упрощает весь процесс. #include «someClass.h» намного проще, чем копировать/вставлять класс. Если класс изменяет someClass.h, он изменится, и вы получите это автоматически, иначе вы перестанете синхронизироваться. someClass может потребовать otherClass, поэтому someClass.h будет включать otherClass.h и т. д. – plivesey