![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
Mayk |
|
||||||
![]() ^аВаТаР^ сообщение>> ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2616 Регистрация: 22.5.2005 Где: за границей разум а Репутация: 45 Всего: 134 |
Инклюд в .cpp, define в .h
По желанию, но лучше использовать чтоб потом не думать, почему компилятор не видит идентификатор "aaa", который был заменен препроцессором на "".
Нет, если только функции не объявлены как inline или static. -------------------- Здесь был кролик. Но его убили. Человеки < кроликов, йа считаю. |
||||||
|
|||||||
Denn |
|
||||||||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 143 Регистрация: 6.8.2005 Репутация: нет Всего: 2 |
Mayk
Я написал следующий код (компилятор vc): a.h:
b.h:
a.cpp:
b.cpp:
Как видно, файл, содержащий объявление func() включается дважды. Однако все компилится и компонуется нормально. Причем при просмотре объектных файлов func() обнаруживается только в b.obj. Это происходит потому, что компилятор работает не с файлом исходного кода как такогого, а с единицей трансляции, которая получается после обработки кода препроцессором. |
||||||||||
|
|||||||||||
Mayk |
|
||||||||||
![]() ^аВаТаР^ сообщение>> ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2616 Регистрация: 22.5.2005 Где: за границей разум а Репутация: 45 Всего: 134 |
#pragma once тут не при чём. Ты можешь в хедере(да где угодно) сотню раз объявить void func(), и всё будет компилироваться нормально. Попробуй откомпилировать вот это:
Сколько ошибок в этом коде? Как бы там ни было, напомню код с которого всё началось:
В хедере нельзя описывать тело ф-ции, если только ф-ция не объявлена как inline, или static(static ф-ция в хедере - это довольно оригинально ![]()
Не совсем верно. Она включается один раз на каждый .cpp файл. Мы не имеем право говорить "включается дважды" для независимых друг от друга процессов(а компиляция a.cpp, повторюсь, НИКАК не зависит от компиляции b.cpp. Ну вообще никак. Если только по мазохистким соображениям не делать #include "a.cpp"). Это сродни тому, что сказать, что у двух людей одно сердце: как каждый человек получает собственное сердце при рождении, так и при компилирования каждый .cpp файл получает свою копию заголовка. При компиляции b.cpp компилятор НЕ БУДЕТ знать, что заголовок func.h уже включался в a.cpp. Откуда ему это знать, собственно говоря? Неоткуда. Да и зачем ему это знать? -------------------- Здесь был кролик. Но его убили. Человеки < кроликов, йа считаю. |
||||||||||
|
|||||||||||
mr.Anderson |
|
|||
![]() iOS Lead Developer ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3374 Регистрация: 20.12.2004 Где: далеко Репутация: нет Всего: 128 |
Что-что?! А я описал в своем хедере много прототипов и самих функций, подключаю его - и все нормально работает. А если нельзя в хедере, то где же тогда? А прототипы куда пхать? |
|||
|
||||
Artiom |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1031 Регистрация: 11.3.2003 Где: Минск\Баку Репутация: нет Всего: 17 |
Реализацию функции можно описать где угодно. -------------------- Если тебя жизнь трахает, значит, ты ещё живой |
|||
|
||||
Mayk |
|
||||||||||
![]() ^аВаТаР^ сообщение>> ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2616 Регистрация: 22.5.2005 Где: за границей разум а Репутация: 45 Всего: 134 |
Только хедер - не самое подходящее место для этого: a.cpp:
b.cpp
a.h
-------------------- Здесь был кролик. Но его убили. Человеки < кроликов, йа считаю. |
||||||||||
|
|||||||||||
mr.Anderson |
|
|||
![]() iOS Lead Developer ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3374 Регистрация: 20.12.2004 Где: далеко Репутация: нет Всего: 128 |
Ну, не знаю. Я описал свои функции работы с файлом в хедере, когда надо, я его подключаю. И все нормально вызывается и работает.
Добавлено @ 13:12 А "где угодно" - это где? И нафига тогда вообще хедер создавать? |
|||
|
||||
Mayk |
|
||||||
![]() ^аВаТаР^ сообщение>> ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2616 Регистрация: 22.5.2005 Где: за границей разум а Репутация: 45 Всего: 134 |
Чтобы описывать прототипы ф-ций и классов. НЕ тела функций, а только объявления:
Тело
по хорошему должно лежать в .cpp. -------------------- Здесь был кролик. Но его убили. Человеки < кроликов, йа считаю. |
||||||
|
|||||||
mr.Anderson |
|
|||
![]() iOS Lead Developer ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3374 Регистрация: 20.12.2004 Где: далеко Репутация: нет Всего: 128 |
Дык я вижу смысл создания хедера в том, чтобы по тридцать раз потом функцию-то не описывать! Создал один раз хедер, потом его подрубил и вызвал оттуда функцию, совершенно не вспоминая, а как же она написана. В этом и смысл хедера, я полагаю... Ведь мы, подключая файл <stdio.h>, не описываем функцию printf(), а просто вызываем и пользуемся ей, верно ведь?
|
|||
|
||||
Mayk |
|
|||
![]() ^аВаТаР^ сообщение>> ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2616 Регистрация: 22.5.2005 Где: за границей разум а Репутация: 45 Всего: 134 |
Тело printf'а лежит в заголовке? Нет, там только объявление типа int printf(const char*fmt, ...);
Тело скомилированным лежит в библиотеке(кстати, еще одна причина по которой не стоит писать тела ф-ций в хедере - скорость компиляции проекта падает, так как один и тот же код компилится по тридцать раз). -------------------- Здесь был кролик. Но его убили. Человеки < кроликов, йа считаю. |
|||
|
||||
mr.Anderson |
|
|||
![]() iOS Lead Developer ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3374 Регистрация: 20.12.2004 Где: далеко Репутация: нет Всего: 128 |
В библиотеке?! Это в DLL, что ли? А... Нда, спрашивать, как ее делать и как они взаимосвязаны, думаю, вы не ответите...
![]() ![]() |
|||
|
||||
Denn |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 143 Регистрация: 6.8.2005 Репутация: нет Всего: 2 |
Mayk
Если уж шаришь, поясни плиз. ![]() Каким образом и в каком порядке подключаются хедеры? Почему, если в хедере объявлена функция, получается, что она подключается несколько раз, почему и этом случае не прокатывает #pragma once? |
|||
|
||||
mr.Anderson |
|
|||
![]() iOS Lead Developer ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3374 Регистрация: 20.12.2004 Где: далеко Репутация: нет Всего: 128 |
Mayk, ПЛИЗ! Скажите, как увязать DLL и хедер? И еще: создать DLL-библиотеку по учебнику я еще смогу, а вот как ее делать для таких вот консольных приложений? Объясните плиз сами или дайте ссылочку на нужную литературу.
Добавлено @ 16:32 И еще один вопрос забыл задать: что такое inline и static для функций? Для других случаев я знаю только для чего static в переменных. К примеру, что такое
мне понятно. Т.е. тут x при новом проходе цикла не возвращается снова на ноль (если я правильно вспомнил этот пример из учебника...). Кстати, а const и static различны или нет по своему действию? А вот что такое inline и что такое static для функций, прошу вас мне объяснить. Это сообщение отредактировал(а) sim7 - 22.8.2005, 16:33 |
|||
|
||||
Mayk |
|
||||||||||||||||||||||||||||||
![]() ^аВаТаР^ сообщение>> ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2616 Регистрация: 22.5.2005 Где: за границей разум а Репутация: 45 Всего: 134 |
Вот, млин, навалились на Майка
![]()
Заместо директивы инклюд препроцессор вставляет и парсит содержимое файла. Следующие две конструкции ПОЛНСОТЬЮ эквивалентны для компилятора... 1) a.cpp:
2) a.h
a.cpp
...потому, что после прохода препроцессором по a.cpp получится код
который и будет передан компилятору
в порядке объявления.
Потому что директива #pragma once означает, что данный файл не должен больше подключаться при компилировании именно этого объектного файла, а не какого-то другого(что вполне логично). После прохода препроцессором по файлу a.cpp(мой предпредыдущий пост) получится следующий кот: a_cpp_preprocessed:
Который будет успешно скомпилирован в a.obj. Значит, в файле a.obj будут содержаться следующие ф-ции:
После прохода препроцессором по b.cpp получится
Это тоже успешно скомпилируется. В файл b.obj будут содержаться сл-ие ф-ции:
Далее файлы a.obj и b.obj отдаются на съедение линкеру, который разбирает какую ф-ции из какого .obj/.lib выдрать. И что же получает комрад линкер? Он получает 4 ф-ции: int a(void); //из a.obj int main(void); //из a.obj int a(void); //из b.obj int b(void); //из b.obj встречая второе определение тела a() он, конечно, ругается. #pragma once не существует для линкера. Где он должен её увидеть, эту pragma once?
[offtop]я предпочитаю обращение "ты"[/offtop]
Что означает "увязать .dll и хедер"? Чтобы при объявлении ф-ции в хедере они вызывались из такой-то библиотеки? Ух, mydll.h:
loadmydll.cpp:
Что-то типа того. Но вообще один топик - один вопрос. ЗЫ. Кстати, printf может подключатся совсем не из dll. Он может подключатся из статической либы - как если бы линкеру .obj подсунили. Это сообщение отредактировал(а) Mayk - 22.8.2005, 19:14 -------------------- Здесь был кролик. Но его убили. Человеки < кроликов, йа считаю. |
||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||
mr.Anderson |
|
|||
![]() iOS Lead Developer ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3374 Регистрация: 20.12.2004 Где: далеко Репутация: нет Всего: 128 |
Вопрос 1: не можешь дать мне ссылку на более-менее понятную литературу по этому делу?
Вопрос 2: ты не ответил на вопросы о static и inline. [offtopic]Ух, до того тяжело на "ты" обращаться, честное слово...[/offtopic] Добавлено @ 17:28 Стоп, еще вопрос 3: объясните плиз пошагово строчку
Добавлено @ 17:29 Да, и еще: зачем еще раз объявлять функцию в твоем *.cpp-файле? И еще: после extern обязательно должен быть тип int? А после него - обязательно скобки? Или что? |
|||
|
||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |