Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.80/15: Рейтинг темы: голосов - 15, средняя оценка - 4.80
260 / 208 / 99
Регистрация: 13.12.2015
Сообщений: 1,098
1

Раздельная компиляция (нюансы использования заголовочных файлов и файлов реализации)

07.01.2016, 14:01. Показов 2821. Ответов 21
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Почему во многих учебниках функции-члены класса внутри класса только объявляют, но определяют вне самого класса (не, ну как бы в классе, но вне) пример ниже

C++
1
2
3
4
5
class C {
int func(int n);// о,]объявляем
}
// дальше "выходим" из класса и определяем
int C::func(int n){return n+1;}
почему не определить сразу в классе?

C++
1
2
3
class C {
int func(int n){return n+1;};
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
07.01.2016, 14:01
Ответы с готовыми решениями:

Подключение заголовочных файлов и файлов реализации
Здравствуйте,при создании класса в visual studio руками не компилится проект,при создании через add...

Раздельная компиляция файлов
Если класс определен в раздельных файлах и изменения сделаны в части main программы, кот использует...

Раздельная компиляция файлов в проекте. Межмодульное взаимодействие
Задан проект-модель почтового сервера Созданы файлы: интерфейс сервера: server.h, интерфейс...

не разберусь как переработать программу с учетом использования заголовочных файлов, модулей и пользовательских функций
#include <iostream.h> #include <stdio.h> #include <conio.h> #include <stdlib.h> #include...

21
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
07.01.2016, 14:17 2
Цитата Сообщение от SergioO Посмотреть сообщение
почему не определить сразу в классе?
1.
что бы не загромождать декларацию.

хэдер - "заголовок" по другому.
как оглавление в книге.
смотришь на прототипы, и сразу понятно,
что есть в классе, а чего нет.
это - удобно.

2.
код, похороненный в спп файле скомпиляется один раз.
а использоваться будет множеством ед. трансляций.

код, определенный в хэдере будет перекомпиляццо каждый раз заново,
для каждой очередной ед. трансляции.
каждый раз при изменении реализации,
все зависимые ед. трансляции будут заново перекомпилироваться.

это плохо для времени компиляции.


3.
сокрытие кода.

можно собрать библиотеку, и распространять её,
например, в виде product.h и product.lib
хэдер по прежнему будет содержать исходный код в виде текста,
в то время, как product.lib - там уже бинарные данные.
без специальных приседаний будет не понятно,
что там внутри.


в общем, если вкратце:
стремятся по максимуму вынести с хэдеров в cpp файл.
0
6 / 6 / 1
Регистрация: 27.12.2014
Сообщений: 67
07.01.2016, 14:20 3
Цитата Сообщение от SergioO Посмотреть сообщение
почему во многих учебниках функции-члены класса внутри класса только объявляют, но определяют вне самого класса (не, ну как бы в классе, но вне) пример ниже
Для понимая можно посмотреть на функции в С++. Есть реализация функции, есть ее прототип. Вот объявление класса это прототип.
Цитата Сообщение от SergioO Посмотреть сообщение
// дальше "выходим" из класса и определяем
А здесь мы не выходим из него, а реализуем его метод. Так принято писать в С++.
К тому же, если реализовывать метод в объявлении класса, то программист неявно просит компилятор сделать этот метод inline.

И обратите внимание, что объявление класса принято писать в .h файлах, от слова header, т.е. в заголовочных
файлах. Грубо говоря в оглавлении, чтобы рассказать компилятору: "Смотри что у меня есть!".
0
1379 / 406 / 144
Регистрация: 22.10.2014
Сообщений: 872
07.01.2016, 14:20 4
Цитата Сообщение от SergioO Посмотреть сообщение
почему во многих учебниках функции-члены класса внутри класса только объявляют, но определяют вне самого класса (не, ну как бы в классе, но вне) пример ниже
Конкретно в данном случае - если
Цитата Сообщение от SergioO Посмотреть сообщение
// дальше "выходим" из класса и определяем
Это в том же самом заголовочном файле - то делают так "потому что могут".
В случаях посложнее всё растёт из Правило одного определения (One Definition Rule, ODR)
1
260 / 208 / 99
Регистрация: 13.12.2015
Сообщений: 1,098
07.01.2016, 14:42  [ТС] 5
Цитата Сообщение от Kirik516 Посмотреть сообщение
И обратите внимание, что объявление класса принято писать в .h файлах, от слова header, т.е. в заголовочных
файлах. Грубо говоря в оглавлении, чтобы рассказать компилятору: "Смотри что у меня есть!".
я не волшебник, я только учусь )
я делаю просто файл с классом, кладу рядом в папку и потом инструкцией
#include <class>
подключаю его без всяких .h
неправильно так?
0
6 / 6 / 1
Регистрация: 27.12.2014
Сообщений: 67
07.01.2016, 15:05 6
Цитата Сообщение от SergioO Посмотреть сообщение
я делаю просто файл с классом, кладу рядом в папку и потом инструкцией
#include <class>
подключаю его без всяких .h
неправильно так?
Без расширений? Как стринги и все остальное из std?

Ну скорее всего тут нет четкого деления на правильно или неправильно. Поправьте, если не так.
Все зависит от того, как договорится между собой команда разработчиков.
Я предпочитаю делать два файла classname.h и classname.cpp, и писать в них заголовки и реализацию соответственно.
К тому же изначально везде учат делать именно так, как я описал.

Добавлено через 6 минут
Да, и конечно, надо учитывать те особенности, о которых писал hoggy, и особенность связанную с inline.
2
1379 / 406 / 144
Регистрация: 22.10.2014
Сообщений: 872
07.01.2016, 15:11 7
Лучше называть .cpp и .h соответственно исходники и заголовочные файлы.
Цитата Сообщение от SergioO Посмотреть сообщение
#include <class>
#include <class> - поиск файла происходит сначала в системных путях.
#include "class" - сначала в пользовательских.
И использование по верхнему правилу <> "" - это используемая best practice.
1
260 / 208 / 99
Регистрация: 13.12.2015
Сообщений: 1,098
07.01.2016, 17:02  [ТС] 8
Ну скорее всего тут нет четкого деления на правильно или неправильно. Поправьте, если не так.
Все зависит от того, как договорится между собой команда разработчиков.
Я предпочитаю делать два файла classname.h и classname.cpp, и писать в них заголовки и реализацию соответственно.
и потом подключать как
C++
1
2
#include "classname.h"
#include "classname.cpp"
?
Цитата Сообщение от Kirik516 Посмотреть сообщение
К тому же изначально везде учат делать именно так, как я описал.
вас учат, а мы сами с усами ) поэтому будем перенимать ваш опыт )

в чем преимущество поступать именно так, а не как я? ну, функции ниже класса записать как class::func(){}думаю не трудно, но принципиально то потом все закомпилится ведь...
0
1379 / 406 / 144
Регистрация: 22.10.2014
Сообщений: 872
07.01.2016, 17:14 9
Цитата Сообщение от SergioO Посмотреть сообщение
вас учат, а мы сами с усами ) поэтому будем перенимать ваш опыт )
в чем преимущество поступать именно так, а не как я? ну, функции ниже класса записать как class::func(){}думаю не трудно, но принципиально то потом все закомпилится ведь...
Обязательно прочитайте пару книг из "списка литературы" в закреплённых темах.

Цитата Сообщение от SergioO Посмотреть сообщение
и потом подключать как
#include "classname.h"
#include "classname.cpp"
И если вопрос этот останется - приходите
0
260 / 208 / 99
Регистрация: 13.12.2015
Сообщений: 1,098
07.01.2016, 17:20  [ТС] 10
Цитата Сообщение от Nosey Посмотреть сообщение
Обязательно прочитайте пару книг из "списка литературы" в закреплённых темах.
не знаю что там в списке, но у меня литература вся есть и по Си и С++ (Ритчи, Кэрниган, Страуструп, Липман, Шилдт, Пратта и тд и тп)
вот просто когда я их читаю, то и не понимаю ряд вопросов, о которых потом спрашиваю. может неправильно сразу все читать, но: Страуструп малопонятен в илу каких-то выкрутасов без объяснений, Шилдт к Си тяготеет, как я понимаю и тд. Хороший бы задачник с решениями по С++, как в математике чтобы, но чет такого не нахожу. По Си есть, но там совсем учебные примеры, например проинтегрировать то-то, разобрать строку в щепки и потом собрать по-другому, что не интересно. может я не прав. лучше заниматься с преподом и в группе, но что есть уж - другого не намечается.
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
Цитата Сообщение от SergioO Посмотреть сообщение
в чем преимущество поступать именно так, а не как я? ну, функции ниже класса записать как class::func(){}думаю не трудно, но принципиально то потом все закомпилится ведь...
Подключать в этом случает надо так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// h_file.h
#include <all>
#include <used>
#include <headers>
 
class DeclareTheClass
{
// объявляем то, что нам нужно
};
 
//cpp_file.cpp
#include "h_file.h"
 
// реализуем все, что нужно
 
//main_file.cpp
#include "h_file.h"
 
// точка входа в программу
Для чего это делается?
Если реализовать класс внутри его объявление, ты вы неявно попросите компилятор сделать все методы inline.
Чтобы контролировать эти просьбы нужно разделить реализацию и объявление.
Если реализовывать методы в том же файле, что и объявление, то при каждом подключение этого файла, будет
копироваться код реализации. И скорее всего при многократном подключении этого файла, вы получите ошибку
о том, что один и тот же метод несколько раз реализован.
Так как директива #include <some_file> заставит препроцессор полностью скопировать содержание этого файла
в место вызова директивы.

Также hoggy, довольно подробно описал значимость разделения объявления и реализации.

Также не стоит забывать и о следующей конструкции в заголовочных файла, которая предотвращает бесконечное
вложение.
C++
1
2
3
4
5
//h_file.h
#ifndef H_FILE_H
#define H_FILE_H
// все что нам нужно
#endif // H_FILE_H
Добавлено через 2 минуты
Цитата Сообщение от SergioO Посмотреть сообщение
Хороший бы задачник с решениями по С++, как в математике чтобы, но чет такого не нахожу.
Есть в интернете сайты, к сожалению не помню адресов, для подготовки к олимпиадам по программированию.
В них хорошие задачи. Причем, там есть система проверки ответа. Загружаете программу на сайт и она там тестируется
автоматически.
0
260 / 208 / 99
Регистрация: 13.12.2015
Сообщений: 1,098
07.01.2016, 17:53  [ТС] 13
Цитата Сообщение от Nosey Посмотреть сообщение
Прочитайте краткий пересказ: Единица трансляции
вот который раз убеждаюсь что наглядно должны такие вопросы разбираться - как говорил Пуанкаре:"чтобы объяснить обыкновенные дроби нужен нож и торт". на словах все это, особенно новичку мало понятно. вот бы схемкой как типа "мультик" )) "лежит" файлик и тут компилятор его берет и что дальше происходит, что куда включается и не включается... сам бы уже такую фигню сделал, но я подобными пакетами не владею. не хотите заняться? ))

Добавлено через 3 минуты
Цитата Сообщение от Kirik516 Посмотреть сообщение
Так же не стоит забывать и о следующей конструкции в заголовочных файла, которая предотвращает бесконечное
вложение.
а
C++
1
#pragma once
разве не с этой целью или я чего-то путаю?

C++
1
#ifndef
вроде для макросов используется
0
1379 / 406 / 144
Регистрация: 22.10.2014
Сообщений: 872
07.01.2016, 17:54 14
Цитата Сообщение от Kirik516 Посмотреть сообщение
Если реализовать класс внутри его объявление, ты вы неявно попросите компилятор сделать все методы inline.
Мы не просим компилятор, мы лишь даём ему такую возможность, предоставляя код в данной единице трансляции(в cpp файле).
А если он не будет видеть реализацию, а только определение - то оставит это на откуп линковщику -> в общем случае инлайнинга не произойдёт.

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

Вот это ещё можно добавить к верхнему списку ссылок:
Компилятор - С++ использует раздельную компиляцию.
0
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
07.01.2016, 18:03 15
Цитата Сообщение от Nosey Посмотреть сообщение
Мы не просим компилятор, мы лишь даём ему такую возможность,
нет, мы именно что просим.
все методы определённые в декларации класса неявно помечаются inline
1
3257 / 2059 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
07.01.2016, 18:06 16
Цитата Сообщение от SergioO Посмотреть сообщение
вот который раз убеждаюсь что наглядно должны такие вопросы разбираться
Цитата Сообщение от SergioO Посмотреть сообщение
сам бы уже такую фигню сделал, но я подобными пакетами не владею. не хотите заняться?
Задумайтесь на минуту: может ли быть такое, что Вы — единственный в мире, кто задается этими вопросами? Скорее всего, нет. Кажется ли этот материал достаточно общим и базовым, чтобы его основы нужно было объяснять людям? Скорее всего, да. Следовательно, материалы должны быть. Вы их искали? Книги, статьи в гугле, видео на ютубе? Один запрос «Compilation process» выдает кучу результатов, на любой вкус. Понятно, что отвечать за качество подачи материала каждого никто не станет, тем не менее источников информации предостаточно.

Одна из первых попавшихся статей с диаграммами и листингами: link.
3
1379 / 406 / 144
Регистрация: 22.10.2014
Сообщений: 872
07.01.2016, 18:09 17
Цитата Сообщение от hoggy Посмотреть сообщение
все методы определённые в декларации класса неявно помечаются inline
На которую ему с высокой колокольни, если мы не включим оптимизацию.
А если включим оптимизацию, то он заинлайнит всё что сможет, помечена она или нет.

Если не учитывать верхнее, то потом возникнет вопрос "Что происходит при использовании ключевого слова inline?"
0
260 / 208 / 99
Регистрация: 13.12.2015
Сообщений: 1,098
07.01.2016, 18:13  [ТС] 18
Скачал книгу А.Ахо "Компиляторы. Принципы, технологии и инструментарий". буду пробовать ))

Добавлено через 1 минуту
Цитата Сообщение от Nosey Посмотреть сообщение
Если не учитывать верхнее, то потом возникнет вопрос "Что происходит при использовании ключевого слова inline?"
вроде как и ничего даже ) а если функция коротенькая, то может и чего
0
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
07.01.2016, 18:27 19
Цитата Сообщение от Nosey Посмотреть сообщение
На которую ему с высокой колокольни, если мы не включим оптимизацию.
А если включим оптимизацию, то он заинлайнит всё что сможет, помечена она или нет.
монопенисуальный фактор.

выше вы писали, что мы ни о чем не просим компилятор,
а лишь предоставляем ему какие то возможности.

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

и мы имеем полное право так полагать.
стандарт нам это гарантирует.

простейший пример:
мы поклали болт на ODR, но ошибок множественного определения не происходит.
потому что стандарт гарантирует иммунитет для inline функций.

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

inline - ключевое слово языка.
синтаксис - первичен.
любые оптимизации - вторичны.
1
Kirik516
07.01.2016, 18:40     Раздельная компиляция (нюансы использования заголовочных файлов и файлов реализации)
  #20

Не по теме:

Цитата Сообщение от SergioO Посмотреть сообщение
C++
1
#pragma once
разве не с этой целью или я чего-то путаю?
Это все ваши MSVS упоротости. А я под MinGW сижу.

Цитата Сообщение от Nosey Посмотреть сообщение
Это называется header guards.
Название то красивое. Но его могли не понять.

0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
07.01.2016, 18:40

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

Раздельная компиляция: что помещать в заголовочные файлы, а что в файлы реализации (исходники)?
Здравствуйте, я учусь пользоваться Visual Studio.Пишу программу, в которой создаются и разрушаются...

Подключение заголовочных файлов
Начал изучать С++, скачал несколько книг и заметил что в одних при включении заголовочных файлов...

Отличие заголовочных файлов
чем отличается string.h cstring string


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

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