Arhn - архитектура программирования

Заголовочные файлы C++ и файлы реализации: что включать?

Есть файл .h и файл .cpp с одинаковым именем, но с другим расширением.

Если я хочу использовать то, что находится в файле .cpp, включаю ли я файл .h или файл .cpp?



Ответы:


1

Простой ответ заключается в том, что вы почти всегда хотите включать файлы .h и компилировать файлы .cpp. Файлы CPP (обычно) являются истинным кодом, а файлы H (обычно) представляют собой предварительные объявления.

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

То, что делает «include», в основном копирует/вставляет файл в эту строку. Неважно, какое у вас расширение, оно будет включать содержимое файла таким же образом.

Но код C++ по соглашению обычно пишется так:

SomeClass.cpp —

#include "SomeClass.h"
#include <iostream>

void SomeClass::SomeFunction()
{
  std::cout << "Hello world\n";
}

SomeClass.h -

class SomeClass
{
  public:
    void SomeFunction();
};

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

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

Основное предостережение заключается в том, что это соглашение о реализации/упреждающем объявлении не выполняется для кода, использующего шаблоны. Код шаблона по-прежнему будет передаваться вам в виде файлов .h, но он (обычно) реализуется непосредственно в файле .h и не будет сопровождаться файлами .cpp.

22.05.2010
  • +1 отличный ответ, без всякого НИКОГДА. При разделении кода всегда следует руководствоваться здравым смыслом. И да, по соглашению заголовочный файл (*.h) должен быть разработан таким образом, чтобы его можно было безопасно включать везде без наложения каких-либо дополнительных зависимостей или побочных эффектов (например, с использованием пространства имен...) в единице компиляции, в которую он включен. к. 22.05.2010
  • Просто чтобы уточнить, когда вы говорите включить файлы .h и скомпилировать файлы .cpp, вы имеете в виду, что помимо включения файлов заголовков (.h) из вашего так называемого основного класса вы также должны добавить реализацию (.cpp) файлы в строку компилятора вместе с основным классом? 05.03.2013
  • @StockB: Не уверен, что вы подразумеваете под основным классом, потому что в C ++ нет основного класса, но то, что вы говорите, смутно верно. Кроме того, разные компиляторы работают по-разному, поэтому я не могу сказать, что вы определенно можете добавить несколько файлов cpp в командную строку используемого вами компилятора. Основное различие заключается в том, что файлы .h, как правило, включаются, тогда как файлы .cpp обычно передаются непосредственно компилятору. 05.03.2013
  • Под основным классом я имел в виду класс с функцией main(). Я использую GCC и обнаружил, что это действительно приводит к правильной компиляции программы. Раньше я включал файлы .cpp в свой код, пока мой руководитель не указал, что такая практика не рекомендуется и следует включать только файлы .h. Спасибо. 06.03.2013


  • 3

    Обычно лучше писать в заголовочном файле .h

    #ifndef H_someClass
    #define H_someClass
    
    class SomeClass {
    public:
        void SomeFunction();
    };
    
    #endif
    

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

    22.05.2010
    Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..