260 / 208 / 99
Регистрация: 13.12.2015
Сообщений: 1,098
|
|||||||||||
1 | |||||||||||
Раздельная компиляция (нюансы использования заголовочных файлов и файлов реализации)07.01.2016, 14:01. Показов 2821. Ответов 21
Метки нет (Все метки)
Почему во многих учебниках функции-члены класса внутри класса только объявляют, но определяют вне самого класса (не, ну как бы в классе, но вне) пример ниже
0
|
07.01.2016, 14:01 | |
Ответы с готовыми решениями:
21
Подключение заголовочных файлов и файлов реализации Раздельная компиляция файлов Раздельная компиляция файлов в проекте. Межмодульное взаимодействие не разберусь как переработать программу с учетом использования заголовочных файлов, модулей и пользовательских функций |
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
|
|
07.01.2016, 14:17 | 2 |
1.
что бы не загромождать декларацию. хэдер - "заголовок" по другому. как оглавление в книге. смотришь на прототипы, и сразу понятно, что есть в классе, а чего нет. это - удобно. 2. код, похороненный в спп файле скомпиляется один раз. а использоваться будет множеством ед. трансляций. код, определенный в хэдере будет перекомпиляццо каждый раз заново, для каждой очередной ед. трансляции. каждый раз при изменении реализации, все зависимые ед. трансляции будут заново перекомпилироваться. это плохо для времени компиляции. 3. сокрытие кода. можно собрать библиотеку, и распространять её, например, в виде product.h и product.lib хэдер по прежнему будет содержать исходный код в виде текста, в то время, как product.lib - там уже бинарные данные. без специальных приседаний будет не понятно, что там внутри. в общем, если вкратце: стремятся по максимуму вынести с хэдеров в cpp файл.
0
|
6 / 6 / 1
Регистрация: 27.12.2014
Сообщений: 67
|
|
07.01.2016, 14:20 | 3 |
Для понимая можно посмотреть на функции в С++. Есть реализация функции, есть ее прототип. Вот объявление класса это прототип.
А здесь мы не выходим из него, а реализуем его метод. Так принято писать в С++. К тому же, если реализовывать метод в объявлении класса, то программист неявно просит компилятор сделать этот метод inline. И обратите внимание, что объявление класса принято писать в .h файлах, от слова header, т.е. в заголовочных файлах. Грубо говоря в оглавлении, чтобы рассказать компилятору: "Смотри что у меня есть!".
0
|
1379 / 406 / 144
Регистрация: 22.10.2014
Сообщений: 872
|
|
07.01.2016, 14:20 | 4 |
Конкретно в данном случае - если
Это в том же самом заголовочном файле - то делают так "потому что могут".
В случаях посложнее всё растёт из Правило одного определения (One Definition Rule, ODR)
1
|
260 / 208 / 99
Регистрация: 13.12.2015
Сообщений: 1,098
|
|
07.01.2016, 14:42 [ТС] | 5 |
я не волшебник, я только учусь )
я делаю просто файл с классом, кладу рядом в папку и потом инструкцией #include <class> подключаю его без всяких .h неправильно так?
0
|
6 / 6 / 1
Регистрация: 27.12.2014
Сообщений: 67
|
|
07.01.2016, 15:05 | 6 |
Без расширений? Как стринги и все остальное из std?
Ну скорее всего тут нет четкого деления на правильно или неправильно. Поправьте, если не так. Все зависит от того, как договорится между собой команда разработчиков. Я предпочитаю делать два файла classname.h и classname.cpp, и писать в них заголовки и реализацию соответственно. К тому же изначально везде учат делать именно так, как я описал. Добавлено через 6 минут Да, и конечно, надо учитывать те особенности, о которых писал hoggy, и особенность связанную с inline.
2
|
1379 / 406 / 144
Регистрация: 22.10.2014
Сообщений: 872
|
|
07.01.2016, 15:11 | 7 |
Лучше называть .cpp и .h соответственно исходники и заголовочные файлы.
#include <class> - поиск файла происходит сначала в системных путях. #include "class" - сначала в пользовательских. И использование по верхнему правилу <> "" - это используемая best practice.
1
|
260 / 208 / 99
Регистрация: 13.12.2015
Сообщений: 1,098
|
||||||
07.01.2016, 17:02 [ТС] | 8 | |||||
вас учат, а мы сами с усами ) поэтому будем перенимать ваш опыт ) в чем преимущество поступать именно так, а не как я? ну, функции ниже класса записать как class::func(){}думаю не трудно, но принципиально то потом все закомпилится ведь...
0
|
1379 / 406 / 144
Регистрация: 22.10.2014
Сообщений: 872
|
|
07.01.2016, 17:14 | 9 |
Обязательно прочитайте пару книг из "списка литературы" в закреплённых темах.
И если вопрос этот останется - приходите
0
|
260 / 208 / 99
Регистрация: 13.12.2015
Сообщений: 1,098
|
|
07.01.2016, 17:20 [ТС] | 10 |
не знаю что там в списке, но у меня литература вся есть и по Си и С++ (Ритчи, Кэрниган, Страуструп, Липман, Шилдт, Пратта и тд и тп)
вот просто когда я их читаю, то и не понимаю ряд вопросов, о которых потом спрашиваю. может неправильно сразу все читать, но: Страуструп малопонятен в илу каких-то выкрутасов без объяснений, Шилдт к Си тяготеет, как я понимаю и тд. Хороший бы задачник с решениями по С++, как в математике чтобы, но чет такого не нахожу. По Си есть, но там совсем учебные примеры, например проинтегрировать то-то, разобрать строку в щепки и потом собрать по-другому, что не интересно. может я не прав. лучше заниматься с преподом и в группе, но что есть уж - другого не намечается.
0
|
1379 / 406 / 144
Регистрация: 22.10.2014
Сообщений: 872
|
|
07.01.2016, 17:34 | 11 |
SergioO, Хорошо. уговорили, идём на встречу
Прочитайте краткий пересказ: Единица трансляции И ещё раз вот это : Правило одного определения (One Definition Rule, ODR) И как следует подумайте над прочитанным. Вы всё ещё хотите писать Код
#include "classname.cpp" Внизу темы ещё кучка подобных тем.
0
|
6 / 6 / 1
Регистрация: 27.12.2014
Сообщений: 67
|
|||||||||||
07.01.2016, 17:39 | 12 | ||||||||||
Подключать в этом случает надо так:
Если реализовать класс внутри его объявление, ты вы неявно попросите компилятор сделать все методы inline. Чтобы контролировать эти просьбы нужно разделить реализацию и объявление. Если реализовывать методы в том же файле, что и объявление, то при каждом подключение этого файла, будет копироваться код реализации. И скорее всего при многократном подключении этого файла, вы получите ошибку о том, что один и тот же метод несколько раз реализован. Так как директива #include <some_file> заставит препроцессор полностью скопировать содержание этого файла в место вызова директивы. Также hoggy, довольно подробно описал значимость разделения объявления и реализации. Также не стоит забывать и о следующей конструкции в заголовочных файла, которая предотвращает бесконечное вложение.
Есть в интернете сайты, к сожалению не помню адресов, для подготовки к олимпиадам по программированию. В них хорошие задачи. Причем, там есть система проверки ответа. Загружаете программу на сайт и она там тестируется автоматически.
0
|
260 / 208 / 99
Регистрация: 13.12.2015
Сообщений: 1,098
|
|||||||||||
07.01.2016, 17:53 [ТС] | 13 | ||||||||||
вот который раз убеждаюсь что наглядно должны такие вопросы разбираться - как говорил Пуанкаре:"чтобы объяснить обыкновенные дроби нужен нож и торт". на словах все это, особенно новичку мало понятно. вот бы схемкой как типа "мультик" )) "лежит" файлик и тут компилятор его берет и что дальше происходит, что куда включается и не включается... сам бы уже такую фигню сделал, но я подобными пакетами не владею. не хотите заняться? ))
Добавлено через 3 минуты а
0
|
1379 / 406 / 144
Регистрация: 22.10.2014
Сообщений: 872
|
|
07.01.2016, 17:54 | 14 |
Мы не просим компилятор, мы лишь даём ему такую возможность, предоставляя код в данной единице трансляции(в cpp файле).
А если он не будет видеть реализацию, а только определение - то оставит это на откуп линковщику -> в общем случае инлайнинга не произойдёт. Это называется header guards. Вот это ещё можно добавить к верхнему списку ссылок: Компилятор - С++ использует раздельную компиляцию.
0
|
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
|
|
07.01.2016, 18:03 | 15 |
нет, мы именно что просим.
все методы определённые в декларации класса неявно помечаются inline
1
|
3257 / 2059 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
|
|
07.01.2016, 18:06 | 16 |
Задумайтесь на минуту: может ли быть такое, что Вы — единственный в мире, кто задается этими вопросами? Скорее всего, нет. Кажется ли этот материал достаточно общим и базовым, чтобы его основы нужно было объяснять людям? Скорее всего, да. Следовательно, материалы должны быть. Вы их искали? Книги, статьи в гугле, видео на ютубе? Один запрос «Compilation process» выдает кучу результатов, на любой вкус. Понятно, что отвечать за качество подачи материала каждого никто не станет, тем не менее источников информации предостаточно.
Одна из первых попавшихся статей с диаграммами и листингами: link.
3
|
1379 / 406 / 144
Регистрация: 22.10.2014
Сообщений: 872
|
|
07.01.2016, 18:09 | 17 |
На которую ему с высокой колокольни, если мы не включим оптимизацию.
А если включим оптимизацию, то он заинлайнит всё что сможет, помечена она или нет. Если не учитывать верхнее, то потом возникнет вопрос "Что происходит при использовании ключевого слова inline?"
0
|
260 / 208 / 99
Регистрация: 13.12.2015
Сообщений: 1,098
|
|
07.01.2016, 18:13 [ТС] | 18 |
Скачал книгу А.Ахо "Компиляторы. Принципы, технологии и инструментарий". буду пробовать ))
Добавлено через 1 минуту вроде как и ничего даже ) а если функция коротенькая, то может и чего
0
|
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
|
|
07.01.2016, 18:27 | 19 |
монопенисуальный фактор.
выше вы писали, что мы ни о чем не просим компилятор, а лишь предоставляем ему какие то возможности. ну так вот, мы именно, что просим заинлайнить. мы сообщаем компилятору: крутись, как хочешь, но эту функцию мы полагаем встраиваемой. и мы имеем полное право так полагать. стандарт нам это гарантирует. простейший пример: мы поклали болт на ODR, но ошибок множественного определения не происходит. потому что стандарт гарантирует иммунитет для inline функций. при этом нам абсолютно фиолетово, дебаг у нас сейчас, или оптимизации. и вообще, сможет ли компилятор реально оптимизировать, или нет. inline - ключевое слово языка. синтаксис - первичен. любые оптимизации - вторичны.
1
|
Kirik516
|
07.01.2016, 18:40
Раздельная компиляция (нюансы использования заголовочных файлов и файлов реализации)
#20
|
0
|
07.01.2016, 18:40 | |
Про добавление заголовочных файлов в заголовочных файлах Раздельная компиляция: что помещать в заголовочные файлы, а что в файлы реализации (исходники)? Подключение заголовочных файлов Отличие заголовочных файлов Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |