2015-03-30 6 views
0

Это несколько теоретический вопрос ...Несколько определений ... | C++

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

  • Я два отдельных файлов заголовок A и B.

  • обоих заголовков доступ к тем же заголовок H.

  • От А и BI имеет скомпилированные объектные файлы AO и BO.

  • Когда я пытаюсь скомпилировать cpp-файл M, который включает A и B, связывая AO и BO с M, я получаю сообщения об ошибках в нескольких определениях.

  • Функция (s), что сообщение об ошибке (ы) об расположены в Н.

Я предполагаю, что проблема в том, что в обоих АО и ВО-то ссылки или скомпилированный код/из H, так что он появляется дважды, когда я связываю AO ad BO при компиляции M. Я правильно понял проблему, или мне, вероятно, не хватает чего-то элемента?

И если да, то как вам избежать или обойти такую ​​проблему?

Редактировать: Я сказал, что скомпилировал файлы заголовков. Извините, это был неряшливый способ сказать это. Я скомпилировал файлы cpp с реализациями методов класса в заголовочных файлах A и B.

+1

У вас есть полные функции (то есть, включая фактический код внутри '{}' в H? Если да, это не должно быть там, и это проблема. – deviantfan

+0

Предлагаю вам прочитать о ODR http://en.wikipedia.org/wiki/One_Definition_Rule – vsoftco

+0

Возможно, вам стоит опубликовать свой код, трудно понять, что вы сделали, что привело к ошибкам MD. С одной стороны, вы говорите, что вы скомпилировали файлы заголовков, вы не хотите делать – user657267

ответ

1

Вы не должны компилировать .h (заголовок) файлов. A заголовочный файл является исходным файлом C++, который предназначен для включения в другие исходные файлы на C++ с помощью директивы #include.

Единственными файлами, которые вы должны компилировать, являются файлы .cpp, которые часто называют файлами реализации .

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

  • вперед заявлении
  • макросы
  • других #include сек
  • типов
  • экстернов
  • шаблона код
  • прототипы функций

Причина вашей проблемы, вероятно, в том, что вы включили полное определение функции в свой H-файл, и поэтому при компиляции ваших файлов реализации A и B (их следует называть файлами реализации, если вы их компилируете; альтернативно, вы можете думать о переходе определений функций из этих файлов заголовков в отдельные файлы реализации и только компилировать те файлы реализации), функция скомпилируется как в объектные файлы AO, так и в BO. Вот почему связь не удалась; функции умножаются на время привязки.

Чтобы решить эту проблему, вам необходимо переместить любые определения функций, которые у вас есть в H-файле заголовка, в отдельный файл реализации. Поскольку H, похоже, не привязан к какому-либо одному файлу реализации, который у вас уже есть (я говорю это, потому что он является зависимостью от A и B), вероятно, имеет смысл переместить эти определения функций в новый H. файл реализации cpp. В рамках процесса сборки вам необходимо будет собрать H.cpp и связать его с окончательным исполняемым файлом во время соединения.

+1

Вы абсолютно _do_ компилируете заголовочные файлы. Вы просто не делаете это, как единицы. –

+0

Итак, если я свяжусь с HO при компиляции в AO из A.cpp, а затем свяжу его с компиляцией в BO из B.cpp, а затем в третий раз свяжу его с компиляцией M (.exe) из M.cpp, эта проблема не может произойти? Это значит, что HO не каким-то образом «запекается» в какой-либо из других объектных файлов при связывании его для их компиляции? –

+0

Ack, ты технически правильный @LightnessRacesinOrbit. Но вы знаете, что я имел в виду; вы сами не компилируете заголовочные файлы *; их код только включается в единицы перевода через '# include', и вся вещь затем компилируется. – bgoldst

0

Помните ли вы защитники заголовков в ваших заголовочных файлах, иначе вы закончите с этой проблемой.

#ifndef MY_HEADER_H_INC 
#define MY_HEADER_H_INC 

/* Put Header Code Here */ 

#endif // MY_HEADER_H_INC 

Вы в конечном итоге в том числе и тот же файл несколько раз, потому что, как вы заявили, вы заголовок H включены в обоих затем включить каждый. Это звучит как наиболее вероятная причина.

+0

защитники заголовков не помогут с несколькими файлами, каждый из которых содержит один и тот же заголовок, только один раз. – SleuthEye

+0

Это было бы более вероятно, если бы это был класс, а не функции, с ошибкой. – chris

+0

Это не проблема. Включить защитные ограждения защищать только от нескольких включений одного и того же исходного файла в одну и ту же единицу перевода. OP собирает множество единиц перевода, поэтому определения функций в H-файле заголовка будут размножаться во время ссылки, независимо от того, включен ли H в включенный охранник. – bgoldst

0

В C++ вы должны отделить декларации от реализации, чтобы избежать переопределений (как в описанной ситуации). Поместите объявления в файл заголовка filename.h, с каким-либо включением защиты внутри (либо def-based, либо #pragma один раз); поместите свои определения в filename.cpp, который включает заголовок через #include "filename.h". Когда вы компилируете, вы компилируете только файлы .cpp; не пытайтесь скомпилировать заголовки (если вам не нужен предварительно скомпилированный заголовок, которого вы, вероятно, не знаете).

Смежные вопросы