| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > немного о хеадерах |
| Автор: apook 20.9.2007, 12:29 |
| Линкер выдает ошибку -- Error: _DAT defined in module main.cpp is duplicated in module dat.cpp Суть такова: В заголовочном файле dat.h есть структура DAT( там же заполняется ), в файле main.cpp включен файл dat.h и в dat.cpp тоже включен файл dat.h соответственно. Ошибка потому что тип DAT обьявляется дважды, пачиму так 30 минут непоняток.... |
| Автор: Daevaorn 20.9.2007, 12:33 |
если так, то: заполнять её надо один раз. а у тебя получается два. |
| Автор: GrayCardinal 20.9.2007, 12:41 |
| apook, Можно в файле main.cpp записать макрос (перед включением dat.h), к примеру : #define MAIN_CPP а в dat.h #ifdef MAIN_CPP (заполняем) #else (просто объявляем) #endif |
| Автор: apook 20.9.2007, 12:46 |
| Дело в том что она тока там и определяется(то бишь в хеадере) так поправки: структура такая -- struct { char Ы[ 3 ][ 1 ]; //идентификаторы int Г; } DAT={ { "\x1", "\x1", "\x1" }, { 25 } }; надо чтоб эта структура заполнялась только в файле dat.h и именно таким способом |
| Автор: GrayCardinal 20.9.2007, 12:49 |
| apook, Именно таким способом не прокатит Добавлено через 1 минуту и 2 секунды ЗЫ и объявляется дважды НЕ ТИП, а ПЕРЕМЕННАЯ "DAT". |
| Автор: apook 20.9.2007, 13:06 |
| Да это понятно там опечатка, но почему не прокатит не понятно я с этим не согласен, п о ч е м у у у??? |
| Автор: Daevaorn 20.9.2007, 13:10 |
п о т о м у ч т о в С + + т а к н е л ь з я! Определять переменные нужно в cpp файле, а чтобы они были видны не только там есть слово extern. читай доки! |
| Автор: apook 20.9.2007, 13:26 |
| c extern все понятно О, а как сделать? Хотелось заполнить сразу при обьявлении... |
| Автор: archimed7592 20.9.2007, 13:34 | ||
Потому что header - это НЕ отдельный модуль, а всего лишь кусочек другого модуля. В твоём случае этот кусочек фигурирует аж в двух модулях(можешь с тем же успехом убрать include и руками скопировать содержимое своего хэдера в оба модуля), как и дважды фигурирует определение переменной DAT. Так понятно? |
| Автор: apook 20.9.2007, 13:59 |
| Но ведь дело в том что так и надо делать( по правильному, соответственно в main.cpp и функция int main() так что я не могу в этом модуле не включить и в нем dat.h так как из main я пользуюсь данными из структуры DAT), не прокатывает только заполнение структуры при ее обьявлении... я специально вытащил ее из класса только для того чтоб заполнять при обьявлении, в общем стоял перед выбором заполнять ее в конструкторе или таким способом, польстился чето на второй |
| Автор: GrayCardinal 20.9.2007, 14:39 | ||
Ыыыы. LOL. |
| Автор: Earnest 21.9.2007, 19:28 |
| apook, так и заполняй себе при объявлении на здоровье. Только отдели мух от супа, т.е. объявление типа от объявления переменной. Первое - в хедер, второе - в cpp. А не нравится - все претензии к Страуструпу - это он, гад, напридумал... А нет, это даже Керниган с прочими праотцами С... |
| Автор: archimed7592 21.9.2007, 19:38 | ||
apook, не парь мозги ни себе ни нам. Вот тебе пример(хотя их на форуме десятки):
Если это не понятно, то советую обратиться к книге и постараться увидеть там нечто большее, чем "фигу". |
| Автор: apook 22.9.2007, 02:43 | ||||
Ну что-за пример! я б не додумался до такого Заполнять при обьявлении имелось ввиду напр:
проделать сие в хеадере как я теперь понял нельзя.... |
| Автор: archimed7592 22.9.2007, 08:06 |
И чем твой пример отличается от int x = 75;? 0_o Вообще говоря, тебе не плохо было бы узнать разницу между объявлением и определением. "Заполнять"(а точнее, инициализировать) при объявлении нельзя - так устроен язык С++. В хэдере можно делать абсолютно всё, что можно делать в самом модуле(.cpp), но нужно осозновать возможные последствия содеянного. Попробуй задаться для себя вопросом: в чём для тебя принципиальная разница "заполнения" в хэдере или модуле? Думаю, когда ответишь на него, все вопросы сразу отпадут. |
| Автор: apook 22.9.2007, 09:54 | ||
|
| Автор: archimed7592 22.9.2007, 11:16 |
Думаю ответ: хотелось инициализировать общую переменную в одном месте, но ты, почему-то выбрал для этого хэдер(таким образом сделав инициализацию во всех модулях, которые используют этот хэдер), вместо того, чтобы сделать инициализацию в одном из модулей или вообще в отдельном модуле. |
| Автор: apook 22.9.2007, 14:07 | ||
так, если уж разбитраться что подтолкнуло обьявить переменную в хеадере, то скажу что этому предшествовало, предупреждаю что все не очень серьезно. а дело было так, напоминаю что переменная является структурой и вполне вероятно, так как я не совсем ясно представляю всех нюансов достижения будущей программой поставленного результата, эта структура станет массивом структур.. Структура являлась членом некого класса, дойдя до написания конструктора которого я встал перед вопросом заполнения полей структуры( а заполняется она заранее известными данными) , их примерно 10 - 15(полей) т.е не много(чтоб начать плодить хеадеры с коими итак путанница) но и не мало чтоб это незаметно выглядело в конструкторе(строки типа
Кстати уже инициализировал в конструкторе(временно), но однак так и останется.... Сейчас пришло на ум поиграться со значеничми по умолчанию и инициализировать типа статически, но опять же не все компиляторы поддерживают такую фишку в default constructor, есть-ли какие-нибудь соображения?? чты эт не очень серьезно так ка прога и так работть будет |
| Автор: Ln78 22.9.2007, 16:18 | ||
apook, при очень большом желании можно и зайца курить научить (вопрос зачем?). В твоём случае, один из вариантов может быть такой:
В одном из *.cpp файлов нужно определить _DATA. |
| Автор: zkv 22.9.2007, 16:26 | ||
| если инициализацией простой не обойтись, то можно сделать следущее: (надеюсь правильно тебя понял)
|
| Автор: apook 22.9.2007, 16:41 |
| Одной из причин было уменьшение строчек кода, хотяб иллюзия этого Спасибо за предложеннные варианты. |
| Автор: zkv 22.9.2007, 16:55 |
целью должна быть скорее прозрачность кода, а не количество строчек. |
| Автор: apook 28.9.2007, 13:24 |
| как борться с тем что при включении хеадера значительно утяжеляется исполняемый файл, даже если (ради эксперемента) не вызывать ничего из этого файла ? |
| Автор: akizelokro 28.9.2007, 13:28 |
| ради эксперимента попробовать не включать такой хедер |
| Автор: apook 28.9.2007, 14:07 |
| Мне почему-то хочется включить iostream.h Хотя включив просто iostream.h файл не увеличивается, а если вызвать cout то увеличивается с 4.67 kb до 28.9 kb!!! а файл string хватает просто включить и файл увеличивается до 70 kb |
| Автор: archimed7592 28.9.2007, 14:33 |
Странные нынче программисты пошли... no comments |
| Автор: apook 1.10.2007, 07:02 | ||||
товарищ Уолтер Савич говорит что в cpp файле для хеадера следует писать
говорится так-же что при таком включении не надо передавать имя такого файла в параметре компилятора, а так же не надо включать его через include напр: #include"somefile.cpp" на практике это не работает. Работает так:
и имя файла передается с пареметром компилятору что-за ? |
| Автор: archimed7592 1.10.2007, 07:15 |
| apook, ты сам то понял, что написал? |
| Автор: apook 1.10.2007, 08:24 | ||
Да, ну если захотеть не понять то можно и не понять. Извиняюсь я не на экзамене и даже не на уроке чтоб формулировать суперточно. Тебя смутила фраза
|
| Автор: UnrealMan 1.10.2007, 08:41 |
Это вряд ли. Такой бред понять невозможно. |
| Автор: Fazil6 1.10.2007, 08:44 | ||
Извиняюсь, но тут тебе тоже никто не Буратино, чтобы догадываться о чем твоя галиматья и как ее коментировать... |
| Автор: apook 1.10.2007, 08:56 |
| а что именно не понятно то? я чесно не понял... |
| Автор: akizelokro 1.10.2007, 09:11 | ||||
Предположу, что достопочтенный товарищ Савич писал не
а
Также предпоожу, что (насколько я трудно тебя понял) он пытается показать как функции хедера (.hpp,.h файл) возложить на файл с расщирением .cpp. Если это даже близко не так, то мне вас не близко не понять |
| Автор: apook 1.10.2007, 09:32 | ||||
да точно
|
| Автор: apook 1.10.2007, 09:49 | ||
| Все разобраля! Действительно бредово получилось Вот кусочек из примера Уолтера Савича
Смущает комментарий "Хотя в данном файле этого не требуется" находящийся напротив включения #include "list.h", развивая мысль и убрав эту строку получаем ошибку .... has no been declared. Запутал подлец с утра, а я напридумывал черти-че см мой вопрос выше |
| Автор: archimed7592 1.10.2007, 09:58 | ||
Ты на форуме, где ты должен формулировать свои вопросы достаточно точно, чтобы получить адекватные ответы. Ты нафлудил 782 поста и так и не научился, ни вопросы задавать, ни мысли формулировать, ни программировать. На месте модераторов я бы давно тебе влепил бы не одно предупреждение ибо такая халатность и отсутствие уважения к форумчанам(мы тебе чё, обязаны, что ль?) простительны только ньюбам. Я его не читал, но если кусочек не сильно выдран из контекста, то могу лишь посоветовать Савичу пустить себе пулю в лоб, пока это не сделал кто-то другой. |
| Автор: apook 1.10.2007, 11:04 | ||
| archimed7592 твои претензии выдраны из контекста Я ведь не к тебе именно обратился, а к тем кто непосчитает вопрос флудом и не против посоветовать.. зачем так преувеличивать?
Че-за крутизна, не нравлюсь не общайся |
| Автор: UnrealMan 1.10.2007, 12:22 |
| Маленький совет: разберись с тем, что такое единица трансляции и правило одного определения, и узнай, что делают директивы include, ifndef, define, endif. Далее, если с логическим мышлением всё в порядке, тебе станет ясно, что и как надо делать. |
| Автор: archimed7592 1.10.2007, 14:24 | ||
"Крутизна" как раз таки исходит с твоей стороны:
А это: Если бы я понял, я бы наверное не спрашивал бы тебя понял ли ты сам. |
| Автор: JackYF 1.10.2007, 14:27 |
| apook, согласен с UnrealMan и archimed7592. И от себя еще раз попрошу читабельно формулировать задачи, желательно используя знаки препинания в предложениях. За код, приведенный тобой вначале, я бы послал автора штудировать Страуструпа и других хороших товарищей, так как в .cpp-файлах конструкция вида #ifndef... #define........#endif бессмысленна, потому что они и так транслируются один раз. Применима она как раз в хедерах, которые могут включаться не в один .cpp-файл. |
| Автор: zkv 1.10.2007, 16:03 |
| apook, правда непонятно нифига, не заводись Первый раз вижу защиту от двойного подключения в cpp-файле... пропустил страницу обсуждения... |
| Автор: apook 1.10.2007, 17:22 |
Программирование на С++, 4 издание, Уолтер Савич, стр 649 специально нашел в инете электронный вариант прикрепил как-раз эту страницу. Надо поуглубленней изучит книгу тут говорят неплохой автор |
| Автор: Daevaorn 1.10.2007, 17:40 |
Робски тоже "книги" пишет... |
| Автор: archimed7592 1.10.2007, 18:05 |
А теперь разуй глаза и посмотри на 648 страницу. Это не модуль трансляции. Это обычный заголовочный файл с расширением .cpp [не стал читать полностью, но, по всей видимости это пример того как можно "разделить" интерфейс от реализации в случае шаблонов] |
| Автор: apook 1.10.2007, 18:15 |
| Впрочем я что-то подобное говорил в первом вопросе по этому поводу. Все-равно твоя реакция предвзята, че так сразу в штыки... |
| Автор: archimed7592 1.10.2007, 18:22 |
Ни хрена себе предвзята. 5 страниц флуду ни о чём. Давай не будем обсуждать меня или тебя, а будем обсуждать твою проблему. Она исчерпана? |