Форум программистов, компьютерный форум CyberForum.ru

реализация класса в .h файле хорошо или плохо? - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 35, средняя оценка - 4.69
FanOfGun
6 / 6 / 1
Регистрация: 13.10.2012
Сообщений: 101
17.08.2013, 21:48     реализация класса в .h файле хорошо или плохо? #1
все знакомые мне ide разделяют класс на два файла: .h с описанием и .cpp с кодом, но, например, в boost .hpp файлы почти всегда содержат и реализацию классов, т.е. так тоже можно. так в чем тогда разница и когда какой способ нужно применять? заранее благодарен
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
17.08.2013, 23:41     реализация класса в .h файле хорошо или плохо? #21
вы пишите код без ошибок? это очень круто.
вы пишите сразу оптимальный код? это тоже очень круто.
вам не приходится писать какие-то временные варианты для проверки какой либо реализации с целью отрефакторить, оптимизнуть, улучшить дебажность на время? не знаю круто это или нет.
все это мне часто приходится делать при устаканевшемся публичном интерфейсе класса.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
castaway
Эксперт С++
4841 / 2980 / 367
Регистрация: 10.11.2010
Сообщений: 11,013
Записей в блоге: 10
Завершенные тесты: 1
17.08.2013, 23:47     реализация класса в .h файле хорошо или плохо? #22
Цитата Сообщение от DU Посмотреть сообщение
вы пишите код без ошибок? это очень круто.
вы пишите сразу оптимальный код? это тоже очень круто.
Да, я и сам собой иногда горжусь.

Цитата Сообщение от DU Посмотреть сообщение
вам не приходится писать какие-то временные варианты для проверки какой либо реализации с целью отрефакторить, оптимизнуть, улучшить дебажность на время?
А вот тут как никогда удобна заголовочная реализация. Я вижу смысл в разделении на .h и .cpp в случае окончательного варианта при больших объемах кода.
diagon
Higher
 Аватар для diagon
1920 / 1186 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
18.08.2013, 19:50     реализация класса в .h файле хорошо или плохо? #23
Если писать реализацию в цпп, то будет быстрее рекомпиляция, если в хедерах - будет быстрее рантайм за счет инлайнинга. В принципе, можно инлайнить и на стадии линковки, но чем больше становится кода в проекте, тем дороже это удовольствие.
Praktolock
 Аватар для Praktolock
58 / 58 / 0
Регистрация: 29.11.2011
Сообщений: 272
19.08.2013, 05:58     реализация класса в .h файле хорошо или плохо? #24
Один и тот же код из хедера скомпилится столько раз сколько раз он включен в разные cpp файлы, не? Это как-то не правильно.
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
19.08.2013, 09:58     реализация класса в .h файле хорошо или плохо? #25
Цитата Сообщение от FanOfGun Посмотреть сообщение
а изменение .h файла влечет за собой изменеие всех .h и .cpp файлов, которые его включают, правильно ведь пишу?
Правильно, если реализацию класса напишешь в .h файле то и что то изменишь то придется все файлы перекомпилировать которые включают этот .h файл в новые объектный код. Так в gcc. А в других компиляторах хз. как.
castaway
19.08.2013, 11:00
  #26

Не по теме:

Складывается такое чувство, что все поголовно пишут проекты в миллион строк и сотни файлов, и компиляция проходит минут по 30, а если вынести реализацию в заголовок то и все 30.5 минут...

fasked
Эксперт C++
 Аватар для fasked
4924 / 2504 / 180
Регистрация: 07.10.2009
Сообщений: 4,306
Записей в блоге: 1
19.08.2013, 11:11     реализация класса в .h файле хорошо или плохо? #27
Цитата Сообщение от castaway Посмотреть сообщение
Я вижу смысл в разделении на .h и .cpp в случае окончательного варианта при больших объемах кода
Когда проект достигнет серьезных масштабов, то появится осознание того, что лучше бы сразу начали делать правильно.
castaway
Эксперт С++
4841 / 2980 / 367
Регистрация: 10.11.2010
Сообщений: 11,013
Записей в блоге: 10
Завершенные тесты: 1
19.08.2013, 11:13     реализация класса в .h файле хорошо или плохо? #28
...
Цитата Сообщение от castaway Посмотреть сообщение

Не по теме:

Складывается такое чувство, что все поголовно пишут проекты в миллион строк и сотни файлов, и компиляция проходит минут по 30, а если вынести реализацию в заголовок то и все 30.5 минут...

fasked
Эксперт C++
 Аватар для fasked
4924 / 2504 / 180
Регистрация: 07.10.2009
Сообщений: 4,306
Записей в блоге: 1
19.08.2013, 11:41     реализация класса в .h файле хорошо или плохо? #29
Цитата Сообщение от castaway Посмотреть сообщение
Складывается такое чувство, что все поголовно пишут проекты в миллион строк и сотни файлов, и компиляция проходит минут по 30, а если вынести реализацию в заголовок то и все 30.5 минут...
Дело не в полной компиляции проекта, а как раз таки в частичной. Если реализация какого-нибудь очень популярного класса находится в заголовочном файле, то после изменения одной строки в этой реализации, необходимо будет пересобирать практически каждый объектный файл. В обратном случае достаточно будет пересборки только одного объектного файла. А вот тут уже все зависит от размеров проекта. И даже если сборка всего проекта занимает 5 минут, то это все равно несоизмеримо долго по сравнению со сборкой одного файла.
Опять же, make не настолько умен, чтобы самостоятельно определить зависимости и не способен пересобрать все зависимые файлы. Это, в свою очередь, порождает весьма неприятное поведение, когда в один объектный файл заинлайнена уже новая версия класса, а в некоторые другие еще старая. Как говорится, счастливой отладки.
Тот факт, что директива #include просто подставляет содержимое указанного файла это давно известная проблема в мире C++.
castaway
Эксперт С++
4841 / 2980 / 367
Регистрация: 10.11.2010
Сообщений: 11,013
Записей в блоге: 10
Завершенные тесты: 1
19.08.2013, 11:54     реализация класса в .h файле хорошо или плохо? #30
fasked, это все прекрасно понятно. Если внимательно прочитать все мои сообщения, то можно легко понять что речь идет о частном случае, когда проект небольшой, когда класс не популярный. Практика показывает что это намного удобней, при этом не замечаешь разницу в миллисекундах, потраченных на сборку проекта.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16824 / 5245 / 320
Регистрация: 30.03.2009
Сообщений: 14,125
Записей в блоге: 26
19.08.2013, 12:23     реализация класса в .h файле хорошо или плохо? #31
Почему в Си++ реализации классов выносят в заголовочные файлы? Все очень просто. Тело метода класса, определённое внутри описания класса, является inline. Реализации многих шаблонов (в том числе и стандартных контейнеров) основаны на том, что после инстанциации шаблона компилятор видит все конструкторы, деструкторы, методы и весь тот хлам, что подцепится в процессе инстанциации. Дальше компилятор сделает длинный паровоз из inline'ов, после чего код, расположенный в тексте в виде 100500 различных функций и методов, в машинном коде окажется коротким и быстрым. Именно ради производительности разработчики Си++ особое внимание уделили inline'у. Ничего не бывает бесплатно, а потому производительность кода сопровождается медленной компиляцией и всеми прелестями, растущими от необходимости перекомпиляции проекта при изменении одного несчастного inline-метода класса.

Как поступать при написании самодельных классов? Все короткие методы/конструкторы/деструкторы имеет смысл написать внутри класса (или снаружи, но с модификатором inline) в заголовочном файле. В эту категорию включаются все Set/Get'ы. Длинные и тяжёлые методы, которые незачем inline'ить, лучше реализовывать в файлах *.cpp

Добавлено через 1 минуту
Цитата Сообщение от fasked Посмотреть сообщение
Опять же, make не настолько умен, чтобы самостоятельно определить зависимости и не способен пересобрать все зависимые файлы
Для этого пользуются специальными нанотехнологиями: либо строят всезависимости ручками. либо используют автоматические средства типа таких: Makefile: как с использованием gcc строить автоматические зависимости от .h файлов?
Убежденный
Системный программист
 Аватар для Убежденный
14188 / 6203 / 984
Регистрация: 02.05.2013
Сообщений: 10,331
Завершенные тесты: 1
19.08.2013, 13:18     реализация класса в .h файле хорошо или плохо? #32
Цитата Сообщение от Evg Посмотреть сообщение
Дальше компилятор сделает длинный паровоз из inline'ов, после чего код, расположенный в тексте в виде 100500 различных функций и методов, в машинном коде окажется коротким и быстрым.
Компилятор может сделать это и без inline.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16824 / 5245 / 320
Регистрация: 30.03.2009
Сообщений: 14,125
Записей в блоге: 26
19.08.2013, 16:28     реализация класса в .h файле хорошо или плохо? #33
Цитата Сообщение от Убежденный Посмотреть сообщение
Компилятор может сделать это и без inline
Угу, особенно если не видит реализации функции (т.к. они находятся в другом *.cpp). Типа нанокомпилятор
Убежденный
Системный программист
 Аватар для Убежденный
14188 / 6203 / 984
Регистрация: 02.05.2013
Сообщений: 10,331
Завершенные тесты: 1
19.08.2013, 16:36     реализация класса в .h файле хорошо или плохо? #34
Visual C++ и Intel C++ Compiler - нанокомпиляторы ?
kvadro
11 / 9 / 1
Регистрация: 12.03.2012
Сообщений: 127
19.08.2013, 16:50     реализация класса в .h файле хорошо или плохо? #35
Помойму в C++ про inline говорить глупо, разве

C++
1
2
3
4
5
6
struct Foo
{
    int getBar() { return bar; }
  private:
    int bar;
}
Заинлайнит getBar(), если bar приватный?
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16824 / 5245 / 320
Регистрация: 30.03.2009
Сообщений: 14,125
Записей в блоге: 26
19.08.2013, 16:54     реализация класса в .h файле хорошо или плохо? #36
Цитата Сообщение от Убежденный Посмотреть сообщение
Visual C++ и Intel C++ Compiler - нанокомпиляторы ?
Продемонстрируй мне, как глядя на код

C++
class A
{
  A();
};
и не видя тело конструктора, указанные компиляторы могут что-то проинлайнить

Добавлено через 1 минуту
Цитата Сообщение от kvadro Посмотреть сообщение
Заинлайнит getBar(), если bar приватный?
Да. public/provate - это всего лишь свойство на уровне языка. На уровне машинного кода их нет. Для машинного кода private и public методы принципиально ничем не отличаются
kamre
126 / 130 / 4
Регистрация: 25.12.2011
Сообщений: 438
19.08.2013, 17:04     реализация класса в .h файле хорошо или плохо? #37
Цитата Сообщение от Evg Посмотреть сообщение
не видя тело конструктора, указанные компиляторы могут что-то проинлайнить
MSDN:
When /LTCG is used to link modules compiled by using /Og, /O1, /O2, or /Ox, the following optimizations are performed:
  • Cross-module inlining
  • Interprocedural register allocation (64-bit operating systems only)
  • Custom calling convention (x86 only)
  • Small TLS displacement (x86 only)
  • Stack double alignment (x86 only)
  • Improved memory disambiguation (better interference information for global variables and input parameters)
Убежденный
Системный программист
 Аватар для Убежденный
14188 / 6203 / 984
Регистрация: 02.05.2013
Сообщений: 10,331
Завершенные тесты: 1
19.08.2013, 17:19     реализация класса в .h файле хорошо или плохо? #38
Цитата Сообщение от Evg Посмотреть сообщение
Продемонстрируй мне, как глядя на код
...
и не видя тело конструктора, указанные компиляторы могут что-то проинлайнить
Могут.

Если более конкретно:
IPO в Intel C++
http://software.intel.com/sites/prod...s_ipo_mult.htm

LTCG в Visual C++
http://msdn.microsoft.com/en-us/libr...(v=vs.90).aspx
http://msdn.microsoft.com/en-us/magazine/cc301698.aspx

У GCC также есть соответствующие опции, но я с ним не работаю, поэтому ссылку не приведу.

Ну и специально для тех, кто, как и я, верит только глазам.

Компилируем в Visual C++ 2008 проект с таким кодом:
C++
1
2
3
4
int my_function()
{
    return 0x12345;
}
В итоге получаем объектный файл (.obj).

Теперь создаем второй проект (чтобы не было подозрений) с таким кодом:
C++
1
2
3
4
5
6
int my_function();
 
int main()
{
    return (my_function());
}
И подключаем к нему собранный ранее объектник.
Конфигурация Release, настройки оптимизации по умолчанию.

Вызов функции my_function и ее реализация находятся в разных cpp файлах.
Формально даже в разных единицах компоновки. Однако вот что получилось в
сгенерированном ассемблерном листинге:
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
; Listing generated by Microsoft (R) Optimizing Compiler Version 15.00.30729.01 
 
    TITLE   d:\Dev\App\Test\main.cpp
    .686P   .XMM
    include listing.inc
    .model  flat
 
INCLUDELIB OLDNAMES
 
PUBLIC  _main
; Function compile flags: /Ogtpy
; File d:\dev\app\test\main.cpp
;   COMDAT _main
_TEXT   SEGMENT
_main   PROC                        ; COMDAT
 
; 5    :     return (my_function());
 
    mov eax, 74565              ; 00012345H
 
; 6    : }
 
    ret 0
_main   ENDP
_TEXT   ENDS
END
castaway
Эксперт С++
4841 / 2980 / 367
Регистрация: 10.11.2010
Сообщений: 11,013
Записей в блоге: 10
Завершенные тесты: 1
19.08.2013, 17:39     реализация класса в .h файле хорошо или плохо? #39
Цитата Сообщение от Убежденный Посмотреть сообщение
У GCC также есть соответствующие опции, но я с ним не работаю, поэтому ссылку не приведу.
В GCC это называется LTO (Link-Time Optimization). Включается опцией: -flto

Добавлено через 13 минут
Если быть точным, то в GCC это называется IPA, а LTO лишь расширяет это понятие.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.08.2013, 17:58     реализация класса в .h файле хорошо или плохо?
Еще ссылки по теме:

C++ Переменные на русском языке - хорошо или плохо?
Реализация шаблонов класса в инлайн файле C++
C++ Реализация шаблонов класса в инлайн файле

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

Или воспользуйтесь поиском по форуму:
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16824 / 5245 / 320
Регистрация: 30.03.2009
Сообщений: 14,125
Записей в блоге: 26
19.08.2013, 17:58     реализация класса в .h файле хорошо или плохо? #40
Поднимите руку те, кто использовал режим межмодульного inline в реальных больших проектах, состоящих из десятков тысяч файлов, которые в помодульном режиме собираются несколько часов. Думаю, таких извращенцев нет и в ближайшем обозримом будущем не появится

При написании классов ни в коем случае не надо закладываться на подобные режимы. Нормальные люди ими мало пользуются.

Теперь возьмём ещё один пример. Мы поставляем библиотеку в виде "бинарник библиотеки + инклюды". Что у нас в этом случае может сделать компилятор в этом нанорежиме? Да ничего не сможет. Если мы поставляем библиотеку в виде бинарника, значит мы не хотим показывать её внутренности, значит мы не будем её компилировать в подобных режимах. А потому нужно нормально в хидера прописать все короткие inline-методы и inline-функции (внутренности которых прятать не критично, т.к. и ежу понятно, что в них написано)

Хочется ещё раз подчеркнуть. При разработке софта выбросьте из головы эти идиотские режимы и рассчитывайте эффективность исходя из нормального помодульного режима. А всякие межмодульные inline появились не от хорошей жизни.
Yandex
Объявления
19.08.2013, 17:58     реализация класса в .h файле хорошо или плохо?
Ответ Создать тему
Опции темы

Текущее время: 17:43. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru