Зачем нужны заголовочные файлы и файлы .cpp? [закрыто]

Как видно из большинства проголосовавших комментариев на странице руководства PHP о rmdir() (см. http://php.net/manual/es/function.rmdir.php ), функция glob() не возвращать скрытые файлы. scandir() предоставляется в качестве альтернативы, которая решает эту проблему.

Алгоритм, описанный там (который работал как шарм в моем случае):


457
задан 8 revs, 5 users 60% 28 May 2017 в 16:58
поделиться

8 ответов

Ну, главная причина была бы для разделения интерфейса от реализации. Заголовок объявляет то, "что" сделает класс (или независимо от того, что реализуется), в то время как cpp файл определяет, "как" это выполнит те функции.

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

Это не прекрасно, и Вы обычно обращались бы к методам как Идиома Pimpl для надлежащего разделения интерфейса и реализации, но это - хорошее начало.

194
ответ дан 2 revs, 2 users 75% 28 May 2017 в 16:58
поделиться

Это - препроцессор способ объявить интерфейсы. Вы помещаете интерфейс (объявления метода) в заголовочный файл и реализация в cpp. Приложения, пользующиеся Вашей библиотекой только, должны знать интерфейс, к которому они могут получить доступ через #include.

6
ответ дан Martin v. Löwis 28 May 2017 в 16:58
поделиться
  • 1
    Хорошо мы полностью размышляем здесь;) Никто действительно уверенный, что хочет OP. Это просто напомнило мне моя собственная работа, где .copy() более подходит. Почему бы не сохранять эту опцию открытой? Даже это не то, что он хочет, мудрый образованием, читатели могут изучить что-то. – Wang 15 July 2012 в 15:15

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

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

54
ответ дан unwind 28 May 2017 в 16:58
поделиться
  • 1
    Так... you' ре, защищающее, который пользователь использует .copy() метод вместо того, чтобы просто создать новый словарь по каждому повторению? Я думаю that' s неправильно в этом конкретном случае. – Bryan Oakley 15 July 2012 в 14:52

Поскольку C, где порожденное понятие, 30 лет, и тогда, это был единственный жизнеспособный способ соединить код из нескольких файлов.

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

88
ответ дан jalf 28 May 2017 в 16:58
поделиться
  • 1
    Спасибо за краткое объяснение это - мой первый код с помощью Python: D. Спасибо также за быстрый ответ – l1th1um 15 July 2012 в 17:01

Поскольку люди, которые разработали формат библиотеки, не хотели "тратить впустую" пространство для редко используемой информации как макросы препроцессора C и объявления функции.

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

Большинство языков после C/C++ хранит эту информацию в выводе (Байт-код Java, например), или они не используют предварительно скомпилированный формат вообще, всегда распределяются в исходной форме и компилируют на лету (Python, Perl).

13
ответ дан Aaron Digulla 28 May 2017 в 16:58
поделиться
  • 1
    Во многих случаях Вы можете только сменная деталь объекта в аспекте производительности и краткости, я предпочитаю .copy(). В аспекте образования, .copy() также обеспечивает более ясное понятие. – Wang 15 July 2012 в 15:04

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

В рамках единственного проекта, заголовочные файлы используются, по моему скромному мнению, по крайней мере в двух целях:

  • Ясность, то есть, путем разделения интерфейсов от реализации, легче считать код
  • Время компиляции. Только при помощи интерфейса, если это возможно, вместо полного внедрения, может быть уменьшено время компиляции, потому что компилятор может просто сделать ссылку на интерфейс вместо того, чтобы иметь необходимость проанализировать фактический код (который, идеально, должен был бы только быть сделан единственное время).
5
ответ дан 2 revs 28 May 2017 в 16:58
поделиться
  • 1
    Спасибо за Ваше объяснение. Я изучаю много для you' пример ре. Намерение мая состоит в том, чтобы сделать словарь для каждого iframe, но Ваше объяснение на .copy () полезно для меня – l1th1um 15 July 2012 в 17:11

Компиляция C++

компиляция А в C++ сделана в 2 главных фазах:

  1. первой является компиляция "исходных" текстовых файлов в двоичные "объектные" файлы: файл CPP является скомпилированным файлом и компилируется без любого ведома о других файлах CPP (или даже библиотеки), если не питается к нему через необработанное объявление или включение заголовка. Файл CPP обычно компилируется в.OBJ или файл "объекта".O.

  2. вторым является соединение вместе всех "объектных" файлов, и таким образом, создание заключительного двоичного файла (или библиотека или исполняемый файл).

, Где HPP помещается в весь этот процесс?

А плохой одинокий файл CPP...

компиляция каждого файла CPP независима из всех других файлов CPP, что означает это, если A.CPP нужен символ, определенный в B.CPP, как:

// A.CPP
void doSomething()
{
   doSomethingElse(); // Defined in B.CPP
}

// B.CPP
void doSomethingElse()
{
   // Etc.
}

Это не скомпилирует, потому что A.CPP не имеет никакого способа знать, что "doSomethingElse" существует... Если нет объявление в A.CPP, как:

// A.CPP
void doSomethingElse() ; // From B.CPP

void doSomething()
{
   doSomethingElse() ; // Defined in B.CPP
}

Затем если у Вас есть C.CPP, который использует тот же символ, Вы тогда скопировать/вставить объявление...

СКОПИРОВАТЬ/ВСТАВИТЬ ПРЕДУПРЕЖДЕНИЕ!

Да, существует проблема. Копия/вставки является опасной, и трудной поддержать. Что означает, что было бы здорово, если бы у нас был некоторый путь к НЕ скопировать/вставить, и все еще объявите символ... Как мы можем сделать это? Тем, чтобы включать некоторого текстового файла, который обычно снабжается суффиксом.h, .hxx.h ++ или, мое предпочтительное для файлов C++, .hpp:

// B.HPP (here, we decided to declare every symbol defined in B.CPP)
void doSomethingElse() ;

// A.CPP
#include "B.HPP"

void doSomething()
{
   doSomethingElse() ; // Defined in B.CPP
}

// B.CPP
#include "B.HPP"

void doSomethingElse()
{
   // Etc.
}

// C.CPP
#include "B.HPP"

void doSomethingAgain()
{
   doSomethingElse() ; // Defined in B.CPP
}

, Как делает include работа?

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

, Например, в следующем коде, с заголовком A.HPP:

// A.HPP
void someFunction();
void someOtherFunction();

... источник B.CPP:

// B.CPP
#include "A.HPP"

void doSomething()
{
   // Etc.
}

... станет после включения:

// B.CPP
void someFunction();
void someOtherFunction();

void doSomething()
{
   // Etc.
}

Одна мелочь - почему включают B.HPP в B.CPP?

В текущем случае, это не нужно, и B.HPP имеет doSomethingElse объявление функции, и B.CPP имеет doSomethingElse функциональное определение (который является, отдельно объявление). Но в более общем случае, где B.HPP используется для объявлений (и встроенный код), не могло быть никакого соответствующего определения (например, перечисления, простые структуры, и т.д.), таким образом, включать могло быть необходимо, если B.CPP использует тех объявление от B.HPP. В целом, это - "хороший вкус" к источнику для включения по умолчанию его заголовка.

Заключение

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

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

#ifndef B_HPP_
#define B_HPP_

// The declarations in the B.hpp file

#endif // B_HPP_
573
ответ дан 9 revs, 8 users 84% 28 May 2017 в 16:58
поделиться

Поскольку C++ унаследовал их от C. К сожалению.

14
ответ дан 22 November 2019 в 22:55
поделиться
Другие вопросы по тегам:

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