2009-04-06 2 views
1

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

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

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

[Modulator.h]

прототипов класса модулятора

[ChorusUnit.h] -> Modulator.h

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

[AudioHandler.h] -> ChorusUnit.h

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

[Chorus.cpp] -> AudioHandler.h

определение для членов модулятора и классов Chorus

[AudioHandler.cpp] -> Chorus.cpp

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

[ChorusUnit.cpp] -> AudioHandler.cpp

файл, содержащий функцию Main(), который на самом деле работает код мой проект.

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

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

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

ответ

9

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

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

+0

Я не помещаю #include [header] в .cpp, но все равно дает ссылку на проблему !! еще больше, он дает ошибку для класса в файле, который больше не имеет класса. попытался переместить файл в новое решение, все еще не работающее T_T – Katia

3

[AudioHandler.cpp] -> Chorus.cpp

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

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

+0

Так что я должен переименовать Chorus.cpp в Chorus.hpp? У меня еще нет файла с таким именем в моем проекте. – Rich

+0

Это будет ChorusUnit.h - любой файл, содержащий прототипы для функций, определенных в Chorus.cpp – dirkgently

+0

О, ладно. Я думаю, что понял. Когда я включаю файлы заголовков, мне не нужно также ссылаться на определения в файле .cpp, потому что компилятор/компоновщик сделает это сам, так как я включил заголовок? – Rich

2

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

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

0

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

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