Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.74/35: Рейтинг темы: голосов - 35, средняя оценка - 4.74
2 / 2 / 0
Регистрация: 08.06.2018
Сообщений: 66

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

09.07.2019, 10:35. Показов 7030. Ответов 16
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Почему нельзя определять функции в заголовочных файлах?
Препроцессор ведь просто копирует содержимое заголовка и вставляет после инклуда

Это правила хорошего тона или есть еще какие-то причины?
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
09.07.2019, 10:35
Ответы с готовыми решениями:

Почему в switch нельзя определять переменные?
int main() { setlocale(LC_ALL, "Russian"); int n; std::cout << "Введите число: "; std::cin >> n; switch...

Про добавление заголовочных файлов в заголовочных файлах
В который раз эта вещь засовывает мозги в блендер! Я про то, что не могу однозначно запомнить (основываясь на моих знаниях о директиве...

Константы в заголовочных файлах
declare.h #pragma once extern const size_t rows; extern const size_t cols; double initMatrixInput(double matrix);

16
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
09.07.2019, 10:37
Цитата Сообщение от anton3d Посмотреть сообщение
Почему нельзя определять функции в заголовочных файлах?
Кто сказал что нельзя?
0
Модератор
Эксперт по электронике
8981 / 6748 / 921
Регистрация: 14.02.2011
Сообщений: 23,870
09.07.2019, 10:37
Цитата Сообщение от anton3d Посмотреть сообщение
Препроцессор ведь просто копирует содержимое заголовка и вставляет после инклуда
правильно
и вставит он их после каждого инклуда, во всех файлах
прикинь сколько будет функций, линкер с ума сойдет
0
2 / 2 / 0
Регистрация: 08.06.2018
Сообщений: 66
09.07.2019, 11:27  [ТС]
ValeryS, а что если не пользоватся заголовочными файлами?

g++ main.cpp file1.cpp file2.cpp -o app

в main.cpp будет же доступ к классам и функциям из file1/file2 ?

Я совершенно точно уверен что заголовки придумали не просто так, но пока не докопаюсь почему так,а не иначе не смогу нормально кодить : )

Нагуглил только что-то про малое количество памяти в прошлом,и поэтому компилировали программы по кусочкам вот и прижились заголовки
0
Диссидент
Эксперт C
 Аватар для Байт
27714 / 17332 / 3810
Регистрация: 24.12.2010
Сообщений: 38,978
09.07.2019, 11:44
Цитата Сообщение от anton3d Посмотреть сообщение
Нагуглил только что-то про малое количество памяти в прошлом,и поэтому компилировали программы по кусочкам вот и прижились заголовки
Это вы, уважаемый, чушь нагуглили. Бывает. В инернете много мусора и ерунды.
А обсуждение нужности, полезности инклюдов уже было. Попробую поискать в своих подписках. Не найду - не взыщите

Добавлено через 9 минут
Во, нашел.
В чем преимущество “заголовков” как отдельных файлов?
1
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
09.07.2019, 11:45
Лучший ответ Сообщение было отмечено anton3d как решение

Решение

Цитата Сообщение от anton3d Посмотреть сообщение
Почему нельзя определять функции в заголовочных файлах?
можно.

Цитата Сообщение от anton3d Посмотреть сообщение
Это правила хорошего тона или есть еще какие-то причины?
практичность.

вот например, запихал ты функцию в хедер.
этот хедер прицепил к двум файлам.
допустим, к main.cpp, и foo.cpp

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

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

вот если бы в заголовке было только объявление функции.
а реализация в отдельном спп,
вот тогда пересобирать пришлось бы только этот отдельный спп.
а не все 100500 файлов проекта.
1
Диссидент
Эксперт C
 Аватар для Байт
27714 / 17332 / 3810
Регистрация: 24.12.2010
Сообщений: 38,978
09.07.2019, 11:51
Цитата Сообщение от hoggy Посмотреть сообщение
вот например, запихал ты функцию в хедер.
этот хедер прицепил к двум файлам.
допустим, к main.cpp, и foo.cpp
И если реализации функции не "inline" (о чем думать ТСу еще рановато), то получил ошибку на этапе линковки.
0
Модератор
Эксперт по электронике
8981 / 6748 / 921
Регистрация: 14.02.2011
Сообщений: 23,870
09.07.2019, 11:52
anton3d, давай договоримся о терминологии, а то толку не будет
C++
1
int a (int b);
это что?
C++
1
2
3
4
int a(int b)
{
 return b;
}
а это что?
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
09.07.2019, 12:27
Цитата Сообщение от anton3d Посмотреть сообщение
в main.cpp будет же доступ к классам и функциям из file1/file2 ?
Если вы сами напишете в нем соответствующие объявления.

Цитата Сообщение от anton3d Посмотреть сообщение
компилировали программы по кусочкам
Они и сейчас компилируются точно так же.
Ваша запись в одну строку на самом деле под капотом имеет ту же машинерию по раздельной компиляции каждого из указанных файлов.
0
 Аватар для COKPOWEHEU
4083 / 2681 / 432
Регистрация: 09.09.2017
Сообщений: 11,921
09.07.2019, 17:19
Цитата Сообщение от anton3d Посмотреть сообщение
Нагуглил только что-то про малое количество памяти в прошлом,и поэтому компилировали программы по кусочкам вот и прижились заголовки
Раньше действительно была проблема малой памяти, и пути ее обхода были еще более экзотическими, вплоть до ограничения размера имени переменной.
Но код разделяют на отдельные файлы в основном по другим причинам:
- логическое разделение
- скорость компиляции. Если в каком-нибудь Libreoffice нашли баг и исправили один из файлов, не придется пересобирать вообще все. Достаточно перекомпилировать тот самый один объектник, а потом слинковать с остальными, которые не менялись
- ну и объем памяти тоже. Код-то тоже растет, плюс сотни оптимизаций.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9006 / 4707 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
09.07.2019, 18:32
Цитата Сообщение от Байт Посмотреть сообщение
Во, нашел.
Я бы отметил самостоятельную возможность инклюдов файлов в сpp. Это помогает при связывании крест накрест. То есть, чтобы избежать двойного определения, можно в одном из модулей (пара header - cpp) сделать предварительное объявление в хедере и использовать указатель или ссылку как параметр для функций. А в cpp-шник можно заинклюдить хедер второго из связываемых модулей. Там, в реализациях функций уже нужны возможности обеспечиваемые через тот/те указатели/ссылки, то есть определения.
Теперь первый хедер можно можно инклюдить во второй. Он безопасен так как определений второго хедера там нет (они в cpp1 заинклюжены напрямую).
0
2 / 2 / 0
Регистрация: 08.06.2018
Сообщений: 66
11.07.2019, 10:40  [ТС]
Цитата Сообщение от ValeryS Посмотреть сообщение
1
int a (int b);
обьявление

Цитата Сообщение от ValeryS Посмотреть сообщение
int a(int b)
{
*return b;
}
определение

В общем для меня картина прояснилась)

Спасибо всем ; )
0
-41 / 49 / 5
Регистрация: 10.01.2017
Сообщений: 1,915
31.08.2021, 17:50
Цитата Сообщение от hoggy Посмотреть сообщение
вот например, запихал ты функцию в хедер.
этот хедер прицепил к двум файлам.
допустим, к main.cpp, и foo.cpp

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

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

вот если бы в заголовке было только объявление функции.
а реализация в отдельном спп,
вот тогда пересобирать пришлось бы только этот отдельный спп.
а не все 100500 файлов проекта.
Подскажите пожалуйста, а это, как то влияет на итоговый скомпилированный исполняемый файл ?
То есть, как Вы написали:
- есть у меня main.cpp, и foo.cpp и есть описание и реализация функции или класса в одном .h файле.
- и есть у меня те же main.cpp, и foo.cpp и тот же класс, но разделенный на описание в .h файле, а сам код в .cpp файле.

Но ведь, в обоих случаях все равно нужно и в main.cpp и в foo.cpp делать #include "my_class.h" ?

И вот содержимое итогового exe-шника - будет различаться в этих двух случаях ?
0
 Аватар для COKPOWEHEU
4083 / 2681 / 432
Регистрация: 09.09.2017
Сообщений: 11,921
31.08.2021, 18:42
А проверить? Программирование это такая хорошая штука, в которой можно просто и безболезненно экспериментировавть.

Не по теме:

Ну если не программировать на бейсике... под контроллеры... usb... - вот это весьма болезненно!

0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12938 / 6805 / 1821
Регистрация: 18.10.2014
Сообщений: 17,224
31.08.2021, 18:52
Цитата Сообщение от Optimus11 Посмотреть сообщение
И вот содержимое итогового exe-шника - будет различаться в этих двух случаях ?
Приведите пример в виде кода, а не на словах.
0
-41 / 49 / 5
Регистрация: 10.01.2017
Сообщений: 1,915
31.08.2021, 19:19
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Приведите пример в виде кода, а не на словах.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include "my_Class.h"
#include "My_func.h"
 
 
int main()
{
    my_Class my_Class_;
 
    int result = my_Class_.my_func();
    std::cout << result << std::endl;
 
 
    My_func();
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
class my_Class
{
 
public:
 
    int my_func();
 
 
private:
 
    int my_int;
};
C++
1
2
3
4
5
6
7
8
#include "my_Class.h"
 
int my_Class::my_func()
{
    my_int = my_int / 555;
 
    return my_int;
}
C++
1
2
3
4
5
6
7
8
9
10
#include "my_class.h"
#include <iostream>
 
void My_func()
{
    my_Class my_Class_;
 
    int result = my_Class_.my_func();
    std::cout << result+1 << std::endl;
}















C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include "My_class_header.h"
#include "My_func.h"
 
 
int main()
{
   My_class_header My_class_header_;
 
   int result = My_class_header_.my_func();
   std::cout << result << std::endl;
 
    My_func();
}

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class My_class_header
{
    public:
 
        int my_func()
        {
            my_int = my_int / 555;
 
            return my_int;
        }
 
 
    private:
 
        int my_int;
};
C++
1
2
3
4
5
6
7
8
9
10
#include "My_class_header.h"
#include <iostream>
 
void My_func()
{
    My_class_header My_class_header_;
 
    int result = My_class_header_.my_func();
    std::cout << result+1 << std::endl;
}
Добавлено через 6 минут
Два ехе-файла полностью равны по размеру, но по значению отличаются в двух байтах. Не знаю, что это может или должно значить.
0
68 / 55 / 13
Регистрация: 26.07.2021
Сообщений: 191
02.09.2021, 10:25
Цитата Сообщение от Optimus11 Посмотреть сообщение
Не знаю, что это может или должно значить.
Скорее всего - дата/время сборки EXE-шника.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
02.09.2021, 10:25
Помогаю со студенческими работами здесь

Массивы в заголовочных файлах
в заголовочном файле в описании класса пишу: int _const_iMas = {0x63,0x7c,0x78,0x79}; В итоге компилятор подчёркивает знак '='...

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

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

Определение переменных в заголовочных файлах
Здорова! Определил переменную в заголовочном фале от так #pragma once #ifndef _imya_zagol_fayla #define _imya_zagol_fayla ...

Множественные ошибки в заголовочных файлах
Компилятор DDK выдает кучу ошибок в его же заголовках — winbase.h, wdm.h, ntdef.h, там выходит около сотни ошибок. Основная масса жалуется...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru