Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 28.08.2009, 18:33   #1
Гром
Старожил
 
Аватар для Гром
 
Регистрация: 21.03.2009
Сообщений: 2,193
По умолчанию Заголовочные файлы

Доброго времени суток!
На данном своем жизненном этапе я постигаю мудрость заголовочных файлов, и имею в связи с этим следующие вопросы.
Primo, никак не могу понять, как компилятор, компоновщик и иже с ними собирают вместе программу, использующую библиотеку и саму библиотеку. Например, я пишу библиотеку для геометрических задач. Я создаю файл geom.h, где будут находится все нужные объявления. Затем - файл geom.c (или geom.cpp, а может даже geometr.cpp???). В нем я первым делом включаю geom.h, после чего записываю все необходимые определения, и компилирую его.
В отдаленном светлом будущем я напишу программу, которой понадобится моя геометрическая библиотека. В эту программу я включу geom.h и, когда все напишу, отправлю программу на компиляцию. Собственно, вопрос: достаточно ли этих действий чтобы программа заработала?
Я так себе представляю, что при компиляции .c файла как-то запоминается, что в нем находится реализация (части) того, что объявлено в .h файле, и при запуске программы компоновщик присовокупляет к программе, в которой есть включения этого .h файла все .c файлы, которые содержат реализации объявленного в .h.
Так мне видится, и это единственное объяснение, которое я смог измыслить, не имея четких данных по этому вопросу...

Secundo, как быть с классами, описанными в библиотеке? С одной стороны, [согласно Страуструпу] принято в заголовочные файлы включать определения типов, например
Код:
struct Point {double x, y;};
и для типа точки я считаю это вполне логичным. С другой стороны, определения функций помещаются в .c файлы. И как тогда быть с классами, имеющими функции члены, особенно с громоздким кодом? Стоит ли определять класс Vector вместе со всеми функциями и операторами в geom.h, либо же оставить в нем только
Код:
class Vector;
а реализацию перенести в geom.c? Или же и вовсе - определить класс в .h, а определения функций-членов сослать в .c (тонкое извращение?)?
Простые и красивые программы - коды программ + учебник C++
Создание игры - взгляд изнутри - сайт проекта
Тема на форуме, посвященная ему же
Гром вне форума Ответить с цитированием
Старый 28.08.2009, 18:58   #2
Sazary
В тени
Старожил
 
Аватар для Sazary
 
Регистрация: 19.12.2008
Сообщений: 5,788
По умолчанию

Ну, если включить все файлы в проект, то среда сама найдет cpp файл по имени заголовочного файла. Вроде так.
Если просто создать пустой файл и туда подключить h-файл, то будет жаловаться (undefined reference). По крайней мере, у меня так.

---------------------

В заголовочный файл нужно включать объявление класса, его полей и функций. А в cpp - реализацию.
Пример:

Point.h
Код:
#ifndef Point_h__
#define Point_h__

class Point
{
private:
 double x,y;
public:
  void SetXY(double,double);
  void ShowXY(void); 
};
#endif
Point.cpp:
Код:
#include "Point.h"
#include <iostream>

void Point::SetXY(double a, double b)
{
  x=a; y=b;
}
void Point::ShowXY(void)
{
 std::cout<<x<<","<<y<<std::endl;   
}
Вполне очевидно, чтобы что-то понять, необходимо книги читать.
Не нужно плодить бессмысленных тем. Вас Поиск избавит от многих проблем.

___________________________________ ___________________________________ _______
[=Правила форума=]_____[Поиск]_____[Литература по С++]____[Литература. Паскаль]
Sazary вне форума Ответить с цитированием
Старый 28.08.2009, 19:15   #3
Гром
Старожил
 
Аватар для Гром
 
Регистрация: 21.03.2009
Сообщений: 2,193
По умолчанию

Во всяком случае, как я понимаю, соответствие между именами .h и .c файлов не требуется. Более того, в одном из примеров Страуструп по некоторым соображениям помещает определение функции prim(), объявленной в parser_impl.h в собственный .c файл, а все прочие оставляет в parser.c.
А включение файлов в проект, возможно, и впрямь имеет отношение к разрешению данного вопроса.

За объяснение классов благодарю!))
Простые и красивые программы - коды программ + учебник C++
Создание игры - взгляд изнутри - сайт проекта
Тема на форуме, посвященная ему же
Гром вне форума Ответить с цитированием
Старый 28.08.2009, 21:31   #4
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,065
По умолчанию

h файлы не компилируются в код и их подключение не достаточно. Библиотеки можно распространять в следующих видах:
1) В виде исходников. Придется исходники этой библиотеки добавлять в ваш проект
2) В виде dll. При статической линковке потребуется lib файл и h файлы. К проекту достаточно прилинковать lib-файлик, а хедеры "пихать" в проект не нужно. При динамической линковке библиотеки вообще ничего подключать не нужно в принципе, но скорее всего будет с ней поставляться хедер с прототипами экспортируемых функций
3) В виде статической библиотеки - та же история, что и со статической линковкой dll
В линухе как с динамическими библиотеками дела обстоят не в курсе, так что возможно какие-то изменения будут

Так вот. хедеры в проекте в принципе не нужны. Компилятор на входе получает только cpp файлы из проекта и их компилит, а хедеры находятся только при наличии соответствующего #include.

Процесс сборки программы выглядит примерно следующим образом:
Берём первый cpp файл и пропускаем его через препроцессор.
Вместо #include "my_header.h" вставится текст соответствующего файла.
Защита хедеров вида #ifndef ... #define ... #endif так же построена на препроцессоре и защищает от повторного включения только для данного cpp файла, для другого - этот хедер вставится еще раз и будет заново обрабатываться. Так что прописывая в хедерах переменные, константы,... будьте готовы к их "размножению" внутри программы, т.е. легко появится несколько констант const int MY_GLOBAL_CONST = 10. Так что можете попасть на грабли типа: В одном классе записываем значение в один экземпляр глобальной переменной, а в другом - читаем вроде бы из той же переменной, но из другого её экземпляра.
Так вот. Собрали для каждого cpp файла некий промежуточный объектный файл. Потом из этих файлов уже собираем конечное приложение. Линкеры всякие ищут уже модули с реализацией нужных функций/методов и всё в этом духе.

В общем как-то так. Еще раз повторюсь: не суйте в хедеры ненужную реализацию. В идеале там должно быть тоько описание. Только шаблоны тут являются исключением, просто придется всё в хедере писать и в cpp не получится реализацию вынести.
Вообще подобные темы про хедеры и сипипи поднимались, поищите по форуму, может еще чего полезного найдете.
pu4koff вне форума Ответить с цитированием
Старый 31.08.2009, 15:36   #5
Гром
Старожил
 
Аватар для Гром
 
Регистрация: 21.03.2009
Сообщений: 2,193
По умолчанию

Спасибо, разобрался!)
Во всяком случае все работает если включить в проект geom.cpp, а в нем, и в основном файле вписать #include "geom.h".
Простые и красивые программы - коды программ + учебник C++
Создание игры - взгляд изнутри - сайт проекта
Тема на форуме, посвященная ему же
Гром вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Файлы Archangelos Паскаль, Turbo Pascal, PascalABC.NET 1 01.06.2009 11:27
Заголовочные файлы. C++ Vi_King Помощь студентам 2 03.04.2008 18:47
Файлы xxxPascalxxx Помощь студентам 4 11.03.2008 00:35
два вредных вопроса:про асю и прикриплёные файлы файлы steck Свободное общение 3 17.06.2007 14:53