Работа заголовочных файлов

104
20 августа 2019, 09:00

Возможно вопрос покажется глупым, но я новичок в работе с С++.

Как заголовочный файл знает где брать extern данные/функцию, определение класса... Например у нас есть заголовочный MyClass.h с объявлением класса, а также уйма .cpp файлов с

#include "MyClass.h"

Как он ищет нужный ему файл с определением методов класса?

Answer 1

Если коротко, допустим есть файлы:

main.cpp
List.h
List.cpp

List.h:

#ifndef _LIST_
#define _LIST_
            class List{
        void insert(int a);
    //...
         };
#endif

List.cpp:

#include "List.h"
void List::insert(int a)
{
//...
}

main.cpp:

 #include "List.h"
int main()
{
List list;
list.insert(5);
return 0;
}

.h - файл для объявления

.cpp - файл для определения

1 ) Препроцесор

Обработка макросов, include'ов

List.cpp:

 class List{
           void insert(int a);
          //...
              };

    void List::insert(int a)
        {
        //...
        }

main.cpp:

class List{
           void insert(int a);
          //...
              };
int main()
    {
    List list;
    list.insert(5);
    return 0;
    }

2) Компиляция

На каждую единицу трансляции(cpp файл) создается объектный файл. Будет создано:

List.obj
main.obj

3)Линковка

Связывает объектные файлы и библиотеки (ищет определения методов) и создает исполняемый файл

program.exe
Answer 2

Задача заголовочного файла - обеспечить самостоятельную компилируемость единицы трансляции, включающей этот заголовочный файл. Для этого в заголовочном файле должны присутствовать в первую очередь объявления разнообразных идентификаторов. Никаких "определения методов класса" или "extern данных" для этого не нужно. Поэтому никаким поиском определений заголовочный файл не занимается.

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

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

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

READ ALSO
Минимальный размер QWidget с учетом содержимого

Минимальный размер QWidget с учетом содержимого

Мне необходимо чтобы виджет занимал минимально возможное пространство, но с учетом того, что он не может быть меньше, чем его содержимоеЕго...

97
Как устроен массива типа char?

Как устроен массива типа char?

Когда я создаю char name[] = "John" и пытаюсь разыменовать *name то получаю JЭто значит name сам по себе это адрес? Если да, то адрес чего? Насколько я знаю,...

138
Производительность команд < и <=

Производительность команд < и <=

Давно мучаюсь вопросом есть ли различия между командами меньше и меньше или равно на низком уровне в плане количества команд и производительности?

83