54 / 3 / 2
Регистрация: 17.05.2014
Сообщений: 72
|
|
1 | |
Правильное подключение заголовочных файлов04.08.2014, 22:22. Показов 25591. Ответов 20
Метки нет (Все метки)
Как подключать заголовочные файлы я знаю, но вот у меня есть вопрос, ответ на который я нигде не видел, не видел даже рекомендаций как правильней писать. А ситуация следующая: Допустим у нас есть два класса - one.h (one.cpp) и two.h (two.cpp). В two.h подключен заголовочный файл one.h. А в one.h подключен допустим библиотечный файл iostream. Так вот вопрос, если в two.cpp я хочу воспользоваться одной из функций файла iostream нужно ли мне и в этом классе подключать этот файл? Ведь по сути класс two.h видит iostream через one.h или все таки каждый класс должен быть в этом плане независим от других классов?
И второй вопрос по этой же части. Если я использую функции файла iostream в файле реализации (и нет никаких намеков на это в заголовочном файле), так может вообще нужно подключать файл iostream не в two.h, а в two.cpp. Ну и если есть книги, рассматривающие подобные вопросы архитектуры кода, подскажите плиз) Заранее благодарен!
0
|
04.08.2014, 22:22 | |
Ответы с готовыми решениями:
20
Правильное подключение заголовочных файлов Правильное включение заголовочных файлов Подключение заголовочных файлов Подключение заголовочных файлов |
Заблокирован
|
||||||||||||||||
04.08.2014, 22:30 | 2 | |||||||||||||||
deniska91, сделай заголовочный файл к примеру standerdincl.h пропиши там все стандартные хедеры а в самом верху #pragma once не забудь и потом прописівай первім инклудом в других файлах standerdincl.h
standerdincl
Для чего так - тот кто будет разбирать листинг всегда будет видеть что есть подключение стандартных хедеров прагмы - чтобы хедеры подключались лишь единожды и не было ошибок аля
0
|
503 / 352 / 94
Регистрация: 22.03.2011
Сообщений: 1,112
|
|
04.08.2014, 22:31 | 3 |
Зависит от реализации one и two. Если two является логическим продолжением, то можно и через one подключить общий хедер. Если нет, то по моему, лучше отдельно. Хотя это все условно.
Да. Это предпочтительней. Вообще, такое придет с опытом, выработается собственный или будет навязан общий стиль. Лучше почитать более практические вещи, заодно и посмотрите как другие делают.
1
|
54 / 3 / 2
Регистрация: 17.05.2014
Сообщений: 72
|
|
04.08.2014, 22:32 [ТС] | 4 |
-=ЮрА=-, Спасибо за быстрый ответ. В данном случае iostream я привел для примера, вместо него может быть 3 собственный класс three.h к примеру. Как тогда поступать в этом случае?
0
|
Заблокирован
|
|
04.08.2014, 22:35 | 5 |
- если три нужен всем другим классам и кроме него больше ничего то замени
- прагма не даст произойти множественному подключению и как я уже сказал избежать ошибки с типом "уже объявлено"
Опять е тот кто будет читать твой код будет знать что действительно нужно классу а не рыскать по цепочкам хедеров
1
|
54 / 3 / 2
Регистрация: 17.05.2014
Сообщений: 72
|
|
04.08.2014, 22:42 [ТС] | 6 |
stima, спасибо за ответ.
Вы имеете ввиду книги или исходники? Я стараюсь просматривать С++ проекты на github, хотя это дается с трудом. Добавлено через 3 минуты -=ЮрА=-, по поводу директивы #pragma once я знаю. Меня интересовал вопрос правильности с точки зрения архитектуры программирования.
0
|
503 / 352 / 94
Регистрация: 22.03.2011
Сообщений: 1,112
|
|
04.08.2014, 22:50 | 7 |
Книги. Читать код, тем более не смежного проекта, трудно да и не зачем.
п.с. Пользуйтесь принципом простоты (KISS).
1
|
Ушел с форума
|
|
04.08.2014, 23:06 | 8 |
Сообщение было отмечено deniska91 как решение
Решение
Разумеется !
Это снижает зависимости, а еще может существенно повлиять на время сборки проекта. Один глобальный хидер, в который включено все, что можно - это обычно бывает хорошо лишь в специфических ситуациях, например если используются precompiled headers. В остальных случаях лучше не плодить ненужных включений заголовков, особенно если в какой-то конкретной единице трансляции они вообще не используются.
1
|
|
04.08.2014, 23:54
#9
|
Не по теме: Убежденный, честно странно слышать такое от системного программиста под ВИН.
0
|
Ушел с форума
|
|
05.08.2014, 10:08 | 10 |
Никакого месива здесь нет. Заголовки подключаются только туда, где они реально нужны.
Простейший пример привел автор: в two.h описан интерфейс класса, а two.cpp включает <iostream> и все остальное, что необходимо для реализации. Клиенты класса вообще "не в курсе", что используется в файле реализации, и это хорошо - нет лишних зависимостей, а главное, на мой взгляд - снижение времени компиляции, причем оно может быть существенным. Из личного опыта: проект собирался где-то 20 минут, но после редизайна инклудов это время сократилось примерно до 4-6 минут. Впрочем, если ты используешь stdafx.h и прекомпилированные заголовки, тут другая картина. Что касается already defined и перекрестных/повторных включений - я не понял. Есть же pragma once. От того, что один и тот же заголовок неявно включен в два или более файлов внутри одной единицы трансляции, ошибок не будет. Ну или приведи пример, при котором ошибки такого плана могут возникать. P.S. Кстати, раньше я всегда делал один большой заголовок и по мере написания проекта включал в него все, что требуется. Ни к чему хорошему, кроме увеличения времени компиляции и постоянных пересборках при малейших изменениях в нем (т.к. зависимости лезут во все файлы) это не привело.
0
|
74 / 54 / 17
Регистрация: 10.07.2014
Сообщений: 329
|
||||||
05.08.2014, 11:01 | 11 | |||||
Всегда считал что обрамление в хедере (пример uMain.h)
только препроцессор больше пашет и время компиляции само собой. Чем отличается от этого кода #pragma once?
0
|
Почетный модератор
5850 / 2861 / 392
Регистрация: 01.11.2011
Сообщений: 6,907
|
|
05.08.2014, 11:08 | 12 |
Тем, что pragma once не все компиляторы поддерживают.
И вообще тут разговор идет в .cpp или в .h включать всю эту хренотень.
0
|
05.08.2014, 11:18 | 13 |
+1
При проектировании всегда желательно строить модули с классом таким образом, чтобы они были автономными, а пользователям этих модулей не приходилось постоянно держать в уме миллион особенностей, где, кому и как надо подключать хидера Формировать один файл, который является свалкой для подключения системных хидеров - это порочная практика. Она годится только на начальных уровнях обучения программированию, чтобы не тратить время на вкуривание того, как правильно проектировать программу. Когда выходишь на более-менее серьёзный уровень программирования, то от таких вещей надо отказываться. Особенно для языка Си++, т.к. в стандартных хидерах идут огромные описания шаблонных классов и функций. Если в каждый модуль программы бездумно будет подключаться по 20 заголовочных файлов (через один общий файл-свалку), то для каждого модуля компилятор будет тратить время на пережёвывание всего того барахла, которое растёт из этих файлов, в то время как всё это барахло в реальности оказывается ненужным
1
|
74 / 54 / 17
Регистрация: 10.07.2014
Сообщений: 329
|
|
05.08.2014, 11:20 | 14 |
Чем позже включать, тем лучше. Если есть возможность в .cpp - лучше конечно. Меньше зависимостей. Ну и архитектурное решение - где что описывать и как распределять по файлам - самое главное...
0
|
05.08.2014, 11:25 | 15 |
Не всегда правильно. Возьмём такой пример
C++ /* Файл module.cpp */ #include <iostream> #include "module.h" ... C++ /* Файл module.h */ class MyClass { ... void method (void) { std::cout << "hello"; } ... }; Т.е. ответ на вопрос, где именно писать инклюды, сложно дать формальным образом. Всё зависит от того, как у тебя устроена программа
0
|
Почетный модератор
5850 / 2861 / 392
Регистрация: 01.11.2011
Сообщений: 6,907
|
|
05.08.2014, 11:47 | 16 |
Evg, Убежденный, и в особенности хотелось бы послушать мнение славного -=ЮрА=-, такой конкретный пример:
есть множество классов, выполненных своими отдельными .h и .cpp файлами. И есть другое множество программных модулей, использующих эти классы. Хороша (или не знаю как выразиться) ли следующая реализация их подключения: переписать все файлы используемых классов в отдельный .h файл, который потом подключить в каждом .cpp файле каждого модуля. При чем не все классы используются в каждом модуле, а только лишь часть, и данная реализация позволяет не выписывать каждый требуемый класс в новый создаваемый модуль, а лишь подключать суммирующий заголовок. Какие у нее сильные/слабые стороны?
0
|
05.08.2014, 12:44 | 17 |
Любое разделение на отдельные файлы в первую очередь должно носить идеологический характер и только потом технический. Крайности типа "свалить всё в один файл" или "завести на каждый чих отдельный файл" тоже не уместны. Если ты в один *.h файл свалишь классы "треугольник", "квадрат" и "пятиугольник" - это нормальная ситуация. Если ты в один *.h файл свалишь классы "треугольник", "сотрудник офиса" и "барабан" - это будет выглядеть весьма сомнительно
Добавлено через 30 минут Да, ещё один "бонус" от использования свалки с инклюдами. Предположим, у нас есть проект с 1000 файлов *.cpp. Есть хидер module.h. Из 1000 файлов только 3 файла в реальности потребляют module.h. Но, благодаря наносистеме из одного чудо-хидера, получается, что module.h подцепляется во все 1000 файлов проекта. Далее при изменении в module.h у нас идёт перекомпиляция всех 1000 файлов, хотя при нормальном подходе перекомпилировалось бы только 3 файла
4
|
deniska91
|
05.08.2014, 14:47
[ТС]
#18
|
Не по теме: Спасибо всем за ответы на мой вопрос
0
|
|
||||||||||
05.08.2014, 21:11
#19
|
||||||||||
Не по теме: ...Мы написали 15 классов, некоторые с зависмостями от предыдущих. Мы хотим собрать один большой окнный проект, взаимодействуя между диалогами через указатели на объекты классов. Когда я вижу подобное подключение хедера
А ещё больше нравится когда выкручиваются и делают неполное объявление класса
Да иногда можно обойтись полумерами и подключать лишь то что необходимо, НО такое работает лишь до определённой сложности проекта, а потом начинаются повторные инклуды полотен хедеров, которых легко можно было бы избежать подключив всё в stdafx.h либо подобном по значению файле. Если из вашего опыта вы не встречались с ситуациями когда проект просто нечитабелен из за постоянного беганья по цепочкам хедеров, то я рад за вас, но это ещё ничего не значит... На счёт времени компиляции - с современными то аппаратными средствами на него вообще можно забить отдав предпочтение понятности и элеганстности листинга.
0
|
0 / 0 / 0
Регистрация: 10.09.2012
Сообщений: 25
|
|
05.08.2014, 23:41 | 20 |
Вроде бы уже люди все объяснили, но всеже добавлю. Книга Скотта Майерса "Эффективное использование С++" третье издание.
Правило 31: Уменьшайте зависимости файлов при компиляции. В правиле затрагивается данный вопрос и подробно разбираются причины, но лучше не поленится и прочесть книгу полностью, ибо все советы просветляют разум и наделяют кучей экспириенса)
0
|
05.08.2014, 23:41 | |
05.08.2014, 23:41 | |
Помогаю со студенческими работами здесь
20
Подключение заголовочных файлов. Подключение заголовочных файлов Подключение заголовочных файлов Подключение заголовочных файлов Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |