Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.92/74: Рейтинг темы: голосов - 74, средняя оценка - 4.92
6 / 6 / 4
Регистрация: 13.10.2012
Сообщений: 101
1

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

17.08.2013, 21:48. Показов 15003. Ответов 61
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
все знакомые мне ide разделяют класс на два файла: .h с описанием и .cpp с кодом, но, например, в boost .hpp файлы почти всегда содержат и реализацию классов, т.е. так тоже можно. так в чем тогда разница и когда какой способ нужно применять? заранее благодарен
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
17.08.2013, 21:48
Ответы с готовыми решениями:

Такой способ создание экземпляра класса хорошо или плохо?
Объясните пожалуйста в чем есть плохо создавать экземпляр класса вот так? class A{ ...

Многопоточность - хорошо или плохо?
Начал писать программы с многопоточностью. Имею 64х AMD 4-ядерный. Ранее думал, что на таком...

Google: хорошо или плохо?
давайте по холливарим немного

Ссылки - хорошо или плохо?
Сразу извиняюсь, не смог придумать более вменяемое название. А проблема вот в чем - создаю граф,...

61
DU
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
17.08.2013, 23:41 21
Author24 — интернет-сервис помощи студентам
вы пишите код без ошибок? это очень круто.
вы пишите сразу оптимальный код? это тоже очень круто.
вам не приходится писать какие-то временные варианты для проверки какой либо реализации с целью отрефакторить, оптимизнуть, улучшить дебажность на время? не знаю круто это или нет.
все это мне часто приходится делать при устаканевшемся публичном интерфейсе класса.
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
17.08.2013, 23:47 22
Цитата Сообщение от DU Посмотреть сообщение
вы пишите код без ошибок? это очень круто.
вы пишите сразу оптимальный код? это тоже очень круто.
Да, я и сам собой иногда горжусь.

Цитата Сообщение от DU Посмотреть сообщение
вам не приходится писать какие-то временные варианты для проверки какой либо реализации с целью отрефакторить, оптимизнуть, улучшить дебажность на время?
А вот тут как никогда удобна заголовочная реализация. Я вижу смысл в разделении на .h и .cpp в случае окончательного варианта при больших объемах кода.
0
Higher
1953 / 1219 / 120
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
18.08.2013, 19:50 23
Если писать реализацию в цпп, то будет быстрее рекомпиляция, если в хедерах - будет быстрее рантайм за счет инлайнинга. В принципе, можно инлайнить и на стадии линковки, но чем больше становится кода в проекте, тем дороже это удовольствие.
0
73 / 73 / 18
Регистрация: 29.11.2011
Сообщений: 356
19.08.2013, 05:58 24
Один и тот же код из хедера скомпилится столько раз сколько раз он включен в разные cpp файлы, не? Это как-то не правильно.
0
979 / 196 / 33
Регистрация: 26.09.2012
Сообщений: 2,041
19.08.2013, 09:58 25
Цитата Сообщение от FanOfGun Посмотреть сообщение
а изменение .h файла влечет за собой изменеие всех .h и .cpp файлов, которые его включают, правильно ведь пишу?
Правильно, если реализацию класса напишешь в .h файле то и что то изменишь то придется все файлы перекомпилировать которые включают этот .h файл в новые объектный код. Так в gcc. А в других компиляторах хз. как.
0
castaway
19.08.2013, 11:00
  #26

Не по теме:

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

1
Эксперт С++
5043 / 2622 / 241
Регистрация: 07.10.2009
Сообщений: 4,310
Записей в блоге: 1
19.08.2013, 11:11 27
Цитата Сообщение от castaway Посмотреть сообщение
Я вижу смысл в разделении на .h и .cpp в случае окончательного варианта при больших объемах кода
Когда проект достигнет серьезных масштабов, то появится осознание того, что лучше бы сразу начали делать правильно.
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
19.08.2013, 11:13 28
...
Цитата Сообщение от castaway Посмотреть сообщение

Не по теме:

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

0
Эксперт С++
5043 / 2622 / 241
Регистрация: 07.10.2009
Сообщений: 4,310
Записей в блоге: 1
19.08.2013, 11:41 29
Цитата Сообщение от castaway Посмотреть сообщение
Складывается такое чувство, что все поголовно пишут проекты в миллион строк и сотни файлов, и компиляция проходит минут по 30, а если вынести реализацию в заголовок то и все 30.5 минут...
Дело не в полной компиляции проекта, а как раз таки в частичной. Если реализация какого-нибудь очень популярного класса находится в заголовочном файле, то после изменения одной строки в этой реализации, необходимо будет пересобирать практически каждый объектный файл. В обратном случае достаточно будет пересборки только одного объектного файла. А вот тут уже все зависит от размеров проекта. И даже если сборка всего проекта занимает 5 минут, то это все равно несоизмеримо долго по сравнению со сборкой одного файла.
Опять же, make не настолько умен, чтобы самостоятельно определить зависимости и не способен пересобрать все зависимые файлы. Это, в свою очередь, порождает весьма неприятное поведение, когда в один объектный файл заинлайнена уже новая версия класса, а в некоторые другие еще старая. Как говорится, счастливой отладки.
Тот факт, что директива #include просто подставляет содержимое указанного файла это давно известная проблема в мире C++.
1
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
19.08.2013, 11:54 30
fasked, это все прекрасно понятно. Если внимательно прочитать все мои сообщения, то можно легко понять что речь идет о частном случае, когда проект небольшой, когда класс не популярный. Практика показывает что это намного удобней, при этом не замечаешь разницу в миллисекундах, потраченных на сборку проекта.
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
19.08.2013, 12:23 31
Почему в Си++ реализации классов выносят в заголовочные файлы? Все очень просто. Тело метода класса, определённое внутри описания класса, является inline. Реализации многих шаблонов (в том числе и стандартных контейнеров) основаны на том, что после инстанциации шаблона компилятор видит все конструкторы, деструкторы, методы и весь тот хлам, что подцепится в процессе инстанциации. Дальше компилятор сделает длинный паровоз из inline'ов, после чего код, расположенный в тексте в виде 100500 различных функций и методов, в машинном коде окажется коротким и быстрым. Именно ради производительности разработчики Си++ особое внимание уделили inline'у. Ничего не бывает бесплатно, а потому производительность кода сопровождается медленной компиляцией и всеми прелестями, растущими от необходимости перекомпиляции проекта при изменении одного несчастного inline-метода класса.

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

Добавлено через 1 минуту
Цитата Сообщение от fasked Посмотреть сообщение
Опять же, make не настолько умен, чтобы самостоятельно определить зависимости и не способен пересобрать все зависимые файлы
Для этого пользуются специальными нанотехнологиями: либо строят всезависимости ручками. либо используют автоматические средства типа таких: https://www.cyberforum.ru/c-linux/thread46096.html
0
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
19.08.2013, 13:18 32
Цитата Сообщение от Evg Посмотреть сообщение
Дальше компилятор сделает длинный паровоз из inline'ов, после чего код, расположенный в тексте в виде 100500 различных функций и методов, в машинном коде окажется коротким и быстрым.
Компилятор может сделать это и без inline.
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
19.08.2013, 16:28 33
Цитата Сообщение от Убежденный Посмотреть сообщение
Компилятор может сделать это и без inline
Угу, особенно если не видит реализации функции (т.к. они находятся в другом *.cpp). Типа нанокомпилятор
0
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
19.08.2013, 16:36 34
Visual C++ и Intel C++ Compiler - нанокомпиляторы ?
0
12 / 10 / 1
Регистрация: 12.03.2012
Сообщений: 127
19.08.2013, 16:50 35
Помойму в C++ про inline говорить глупо, разве

C++
1
2
3
4
5
6
struct Foo
{
    int getBar() { return bar; }
  private:
    int bar;
}
Заинлайнит getBar(), если bar приватный?
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
19.08.2013, 16:54 36
Цитата Сообщение от Убежденный Посмотреть сообщение
Visual C++ и Intel C++ Compiler - нанокомпиляторы ?
Продемонстрируй мне, как глядя на код

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

Добавлено через 1 минуту
Цитата Сообщение от kvadro Посмотреть сообщение
Заинлайнит getBar(), если bar приватный?
Да. public/provate - это всего лишь свойство на уровне языка. На уровне машинного кода их нет. Для машинного кода private и public методы принципиально ничем не отличаются
0
127 / 131 / 11
Регистрация: 25.12.2011
Сообщений: 443
19.08.2013, 17:04 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)
0
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
19.08.2013, 17:19 38
Цитата Сообщение от Evg Посмотреть сообщение
Продемонстрируй мне, как глядя на код
...
и не видя тело конструктора, указанные компиляторы могут что-то проинлайнить
Могут.

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

LTCG в Visual C++
http://msdn.microsoft.com/en-u... s.90).aspx
http://msdn.microsoft.com/en-u... 01698.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
3
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
19.08.2013, 17:39 39
Цитата Сообщение от Убежденный Посмотреть сообщение
У GCC также есть соответствующие опции, но я с ним не работаю, поэтому ссылку не приведу.
В GCC это называется LTO (Link-Time Optimization). Включается опцией: -flto

Добавлено через 13 минут
Если быть точным, то в GCC это называется IPA, а LTO лишь расширяет это понятие.
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
19.08.2013, 17:58 40
Поднимите руку те, кто использовал режим межмодульного inline в реальных больших проектах, состоящих из десятков тысяч файлов, которые в помодульном режиме собираются несколько часов. Думаю, таких извращенцев нет и в ближайшем обозримом будущем не появится

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

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

Хочется ещё раз подчеркнуть. При разработке софта выбросьте из головы эти идиотские режимы и рассчитывайте эффективность исходя из нормального помодульного режима. А всякие межмодульные inline появились не от хорошей жизни.
0
19.08.2013, 17:58
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
19.08.2013, 17:58
Помогаю со студенческими работами здесь

Глобальные указатели. Плохо или хорошо?
Уважаемые знатоки, хотел уточнить один вопрос. Дело в том, что я использую глобальные указатели на...

молодняк получил пр=0 хорошо или плохо?
молодой блог ~200 статей. тематика "культура и история" в Г.Панельке словил пр морды 0, раньше не...

Средний балл - хорошо или плохо
С клавиатуры вводятся оценки студента, объемом n, определить средний балл и вывести "хорошо", если...

Статические функции-члены - хорошо или плохо?
Всем привет. Приведу пример такой архитектуры. Есть базовый интерфейс. От него наследуются...


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru