С Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 29, средняя оценка - 4.83
Simyrg
3 / 3 / 0
Регистрация: 22.04.2012
Сообщений: 13
#1

Заголовочный файл или Механизм раздельной компиляции - C++

22.04.2012, 16:27. Просмотров 3867. Ответов 5
Метки нет (Все метки)

Здравствуйте в данный момент я изучаю C++. Среда разработки Visual Studio 2010
Столкнулся с понятием заголовочный файл и из чистого альтруизма решил создать свою библиотеку которую в будущем собираюсь наполнять наиболее часто используемыми функциями. Но не суть.

У меня возникили следующие сложности:
Из определения я понял, что для того чтобы вынести в предкомпилируемый заголовок свою функцию необходимо:
1) создать два файла: один MyLib.h который содержит объявление некоторой функции и другой MyLib.cpp (насколько я понял совпадение имён необязательно) который уже содержит функцию целиком.
Например:
C++
1
2
3
4
5
6
7
//MyLib.h
#ifndef ch_MyLib
#define ch_MyLib
 
int myfunc(int&);
 
#endif ch_MyLib
C++
1
2
3
4
5
6
//MyLib.cpp
#include "MyLib.h" //вот  насчёт этого включения я не понял смысла, одни книги советуют включать другие молчат об этом
int myfunc(int& s) {
    s++;
    return s;   
}
Неважно какой исходный код я написал, это только пример для ясности.

2)В своём исходнике подключить заголовок (#include "MyLib.h") и, по идее, функция будет доступна.

Так вот я совершенно не представляю как заголовочный файл будет искать тело объявленной функции

Когда я по алгоритму описанному выше вынес свою функцию во внешний модуль и подключил в своём исходнике заголовок мне выдало такую вот ошибку
error LNK2019: ссылка на неразрешенный внешний символ (...) в функции _main
Через пару часов гугла и выпученных глаз я понял, что компилятор ругается по совершенно определённой причине - объявление функции он видит а вот тело нет. Собственно я с самого начала это и предпологал.

И вот вопрос. Как мне вынести функцию свою в предкомпилируемый заголовок чтобы я мог подключать её в любой своей программе указав в #include нужный заголовочный файл?

Желательно дать развёрнутый ответ, ато буду опять гуглить сидеть если что-то недопойму
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
22.04.2012, 16:27
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Заголовочный файл или Механизм раздельной компиляции (C++):

Реализация раздельной компиляции - C++
Здравствуйте! Я самоучка поэтому я... Я облазил кучу различных источников, но понял только принцип, по которому...

Порядок раздельной компиляции 3 файлов - C++
Что-то не пойму, объясните мне на пальцах, как откомпилировать три файла (1 заголовочный) вместе. Использую DEV-C++ . coordin.h: //...

Не видно определений функций при раздельной компиляции - C++
Описал класс и его наследника в заголовочном файле; самые громоздкие определения функций вынес в отдельные файлы, однако при...

Как создать объект класса? ПРоблемма из-за раздельной компиляции - C++
Есть 4 файла engine.h - базовый класс engine.cpp - реализация методов базового класса car.h - класс поизводный от engine car.cpp -...

При раздельной компиляции не работает перегрузка операторов ввода-вывода - C++
разделил программу и при компиляции компилятор ругается на объявление перегрузки операторов ввода вывода(на скриншотах видно что он...

Нюансы раздельной компиляции: где и что лучше и правильнее размещать? - C++
Здравствуйте! Допустим, я хочу написать интерфейс класса в h-файле, а его реализацию в cpp-файле. Могу ли я в этом cpp-файле до...

5
Kuzia domovenok
2062 / 1907 / 176
Регистрация: 25.03.2012
Сообщений: 6,572
Записей в блоге: 1
22.04.2012, 17:04 #2
Цитата Сообщение от Simyrg Посмотреть сообщение
Среда разработки Visual Studio 2010
Ну так замечательно. Эти файлы подключены к проекту? Тогда всё слинкуется. Студия сообщит линковщику что куда.
СРР файлы и не должны ни к чему подключаться, они компилируются совершенно раздельно. И при компиляции одного СРР файла совершенно не обязательно знать, какие функции реализованы в другом.
Ты в начале файла пишешь прототип функции, (или подключаешь заголовочный файл с прототипами),
оттуда компилятор узнаёт, какие параметры передавать в функцию, что возвращается и ... всё больше ему ничего не надо.
Он сгегенирует промежуточный код каким-нибудь наподобии
Assembler
1
2
push s;
call myfunc;
А по какому адресу этот myfunc переходит выяснится потом, при сборке всех скомпилированных кусков.
1
Simyrg
3 / 3 / 0
Регистрация: 22.04.2012
Сообщений: 13
22.04.2012, 17:40  [ТС] #3
Я тут поэкспериментирорвал указал файлик в обозревателе и заработало, но почему то ругается на отстутсвие в нём #include "stdafx.h", хотя он присутствует в основном проекте.
Хорошо, тоесть я ручками должен каждый раз указывать где лежит мой файл, в обозревателе решений?
А смысл тогда отграничивать объявление от определения? В смысле не легче ли через #include подключать сразу .cpp, зачем нам необходимо само объявление?

Ещё вопрос, не легче в заголовочном файле ниже приинклудить cpp чтобы не добавлять его в проект?

У меня почему такой вопрос возник, вот подключаю я например iostream - это же заголовочный файл, а уже тело его где-то ещё лежит но среда сама знает где его искать. Ну или я элементарно чего-то просто недопонимаю.
0
Kuzia domovenok
2062 / 1907 / 176
Регистрация: 25.03.2012
Сообщений: 6,572
Записей в блоге: 1
22.04.2012, 18:14 #4
Цитата Сообщение от Simyrg Посмотреть сообщение
А смысл тогда отграничивать объявление от определения? В смысле не легче ли через #include подключать сразу .cpp, зачем нам необходимо само объявление?
Ещё вопрос, не легче в заголовочном файле ниже приинклудить cpp чтобы не добавлять его в проект?
Есть такое понятие - раздельная компиляция. То есть каждый твой cpp файл переводится в машинный код (то есть не совсем в машинный, но не суть)
Так вот он это делает совершенно не зависимо от других. если ты уже сделал часть проекта в одном Cpp файле, и он успешно работает, если в него не вносить изменений, он не будет каждый раз компилироваться заново. Ты можешь использовать функции из него в другом CPP файле.

В больших проектах полное перестроение проекта может занимать очень много времени, к тому же это совершенно не требуется, если надо, скажем проверить твой СРР файл на синтаксические ошибки. Поэтому удобнее работать только с одним СРР файлом, который компилируется совершенно независимо от других.
Единственное, что ему нужно знать это то, что "где-то" существует функция, принимающая int& и возвращающая int. Для её использования, достаточно указать эту информацию, и Будет сгенерирован вызов этой функции, а куда именно ведёт этот вызов - скажет уже линкер, а не компилятор и вообще это будет потом.

Так вот, ты можешь даже не подключать h файл, а вместо этого написать в начале программы
int myfunc(int&);

Вот только если функция нужна в нескольких СРР файлах, то при изменении, скажем типа аргументов, тебе придётся вносить изменения везде, а не только в H файле

Более того, подключать инклудом СРР файлы не только не нужно, но и нельзя.
Ведь если линкер обнаружит в двух файлах проекта одинаковый функции (а это именно так и будет после того как препроцессор прицепит H файл в начало нескольких СРР), он скажет, что у тебя в одной программе две одинаковые функции и это ошибка.
0
gray_fox
What a waste!
1522 / 1227 / 70
Регистрация: 21.04.2012
Сообщений: 2,565
Завершенные тесты: 3
22.04.2012, 18:27 #5
зачем нам необходимо само объявление?
Чтобы вызвать функцию, надо знать её сигнатуру, т.е. имя + типы параметров. Для этого достаточно её объявления, оределение не нужно. Смысл в раздельной компиляции. Когда вы собирете программу, сначала препроцессор обрабатывает все макрокоманды (#include, #define и т.д), потом компилятор компилирует все файлы с исходными кодами (*c, *.cpp) в объктные файлы(*.o, *.obj), каждый исходный файл в один объектный файл. Далее компановщик линкует все объектные файлы в один исполняемый. Если какой-то файл исходного кода остался неизменным с момента предыдущей компиляции, то его не надо компилировать заного, ведь соответствующий объектный файл уже есть, его можно сразу линковать => меньше время компиляции.
Например, если у вас есть уже ранеее собраный проект с тремя *.cpp, вы поменяли один из них. Тогда при сборке будет скомпилирован только он. Если же вы эти файлы свалите в один исходник, то при каждом чихе будуте компилироваться весь код проекта.
вот подключаю я например iostream - это же заголовочный файл, а уже тело его где-то ещё лежит но среда сама знает где его искать.
Среда тут не причём, #include-директивами занимается препроцессор, по сути это просто включение содержимого текста (именно поэтому и надо окружать заголовочные файлы с помощью define-guard). Технически вы можете ими не пользоваться и писать все объявления функций и пр. сами).
1
Simyrg
3 / 3 / 0
Регистрация: 22.04.2012
Сообщений: 13
22.04.2012, 18:38  [ТС] #6
Огромное спасибо, всё предельно ясно.
Ато я с самого начала немного не в ту сторону рассуждать начал..
0
22.04.2012, 18:38
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
22.04.2012, 18:38
Привет! Вот еще темы с ответами:

Как правильно использовать заголовочные файлы при раздельной компиляции в MS Visual Studio? - C++
Если я использую функцию cout и cin в каждом модуле, мне нужно в каждом модуле прописывать : #include <iostream> using namespace std; ...

Создать функцию которая возводит число в квадрат, использовать принцип раздельной компиляции - C++
Создать функцию которая возводит число в квадрат. Использовать принцип раздельной компиляции. Заранее спасибо!

Заголовочный файл - C++
Написал в заголовочном файле вот такой код: #ifndef SALES_DATA_H #define SALES_DATA_H #include <string> struct Sales_Data { ...

Заголовочный файл - C++
Для чево етот файл используется??? Как ево использовать в своей программе помогите хочу разобраться)


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

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.