Сложная ошибка LNK2005: уже определено C ++ - PullRequest
1 голос
/ 06 апреля 2009

Я получаю LNK2005: уже определено в (...) ошибке при построении моего проекта в Visual Studio 2008. Я ссылался на другие связанные вопросы, но мой кажется немного более сложным из-за того, что больше ничего количество файлов, с которыми я работаю.

Во-первых, я думаю, что мне будет полезно отобразить операторы #include, которые есть в файлах моего проекта, в формате [current_file] -> includes_this_file

Все мои файлы заголовков защищены стандартным #ifndef [Header] #define [Header] ... # endif.

[Modulator.h]

прототипы для класса Модулятор

[ChorusUnit.h] -> Modulator.h

прототипы для классов Chorus, которые имеют объекты-члены типа Modulator

[AudioHandler.h] -> ChorusUnit.h

прототипы для класса AudioHandler, который имеет объекты-члены классов Chorus

[Chorus.cpp] -> AudioHandler.h

определения для членов классов Modulator и Chorus

[AudioHandler.cpp] -> Chorus.cpp

определения для членов класса AudioHandler

[ChorusUnit.cpp] -> AudioHandler.cpp

файл, содержащий функцию main (), которая фактически выполняет код моего проекта.

Порядок include включает в себя то, что все определения функций для классов, найденных в Modulator.h, ChorusUnit.h и AudioHandler.h, должны ссылаться на члены других классов, поэтому мне нужны были прототипы, определенные в первую очередь для всех классы, чтобы увидеть друг друга.

Ошибка конкретно говорит о том, что каждое отдельное определение, найденное в Chorus.cpp и AudioHandler.cpp в файле Chorus.obj, уже определено в AudioHandler.obj. Также есть другой набор того же типа ошибки, который говорит, что каждое отдельное определение, найденное в Chorus.cpp и AudioHandler.cpp в файле ChorusUnit.obj, уже определено в AudioHandler.obj.

Вероятно, есть довольно простое решение, но я не особенно опыт (в основном программистом на Java) в общем линковании. Что касается моих ограниченных знаний по этому вопросу, я определил все только один раз, и все было включено только один раз, так что я лично в растерянности относительно того, почему они уже определены. Некоторые, пожалуйста, просветите меня!

Ответы [ 4 ]

9 голосов
/ 07 апреля 2009

Вероятно, ошибка в том, что вы говорите, что #include Chorus.cpp в AudioHandle.cpp - это не то, что вы, вероятно, хотите.

Причина в том, что все файлы .cpp (если вы не сделали что-то особенное в вашей IDE) скомпилированы отдельно, а затем связаны. Когда вы #include другого файла .cpp, текст файла буквально включается; следовательно, все объекты, определенные во включаемом файле, также появляются во включаемом файле. Когда вы связываете два файла, общие объекты вызывают конфликт.

3 голосов
/ 07 апреля 2009

[AudioHandler.cpp] -> Chorus.cpp

определения для членов класса AudioHandler

Это неправильно. Включите ChorusUnit.hpp для прототипов.

2 голосов
/ 07 апреля 2009

AudioHandler.cpp и ChorusUnit.cpp должны только #include заголовочные файлы, но не другие исходные файлы C ++.

Препроцессор вставляет содержимое любого файла #included в файл #inclusive, поэтому вы получаете две копии символов из Chorus.cpp после начала компоновки: одну - от компиляции Chorus.cpp, а другую - от компиляции AudioHandler.cpp. (поскольку он # включает Chorus.cpp).

0 голосов
/ 07 апреля 2009

Я не уверен, как это сделать на компьютерах с Windows, но эти проблемы обычно можно решить, пропустив код ТОЛЬКО через препроцессор C. Это приведет к тому, что объединенный исходный файл по существу заменит все операторы "#include" файлами, на которые они ссылаются. Если вы просмотрите этот объединенный файл, станет очевидно, где что-то переопределяется. В Linux / Unix это можно сделать с помощью команды 'cpp'.

...