Множественное определение одного и того же символа в C ++ (визуальная студия)

У меня проблема с довольно простым кодом
Я следую учебнику chrono :: engine http://www.chronoengine.info/mediawiki/index.php/Demo_fourbar
У меня нет большого опыта в программировании на C ++ (у меня есть некоторый опыт в Java), поэтому я попытался определить MyEventReceiver (класс из учебного пособия) в другом файле (MyEventReceiver.h и MyEventReceiver.cpp), чтобы получить представление о классическом структура кода C ++

Вот версия кода

MyEventReceiver.h

#ifndef RECEIVER_H
#define RECEIVER_H

#include "physics/CHapidll.h"#include "physics/CHsystem.h"#include "irrlicht_interface/CHbodySceneNode.h"#include "irrlicht_interface/CHbodySceneNodeTools.h"#include "irrlicht_interface/CHdisplayTools.h"#include "irrlicht_interface/CHirrWizard.h"#include "core/CHrealtimeStep.h"
#include <irrlicht.h>// Use the namespace of Chrono
using namespace chrono;

// Use the main namespaces of Irrlicht
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

class MyEventReceiver : public IEventReceiver
{
public:
MyEventReceiver(ChSystem* asystem, IrrlichtDevice* adevice,     ChSharedPtr<ChLinkEngine> aengine);
bool OnEvent(const SEvent& event);
void setText_enginespeed(IGUIStaticText* _text_enginespeed);
IGUIStaticText* getText_enginespeed();
private:
IGUIStaticText* text_enginespeed;
ChSystem*       msystem;
IrrlichtDevice* mdevice;
ChSharedPtr<ChLinkEngine> mengine;
};

#endif

с реализацией следующим образом в MyEventReceiver.cpp

#include "MyEventReceiver.h"

// Constructor
MyEventReceiver::MyEventReceiver(ChSystem *asystem, IrrlichtDevice *adevice, ChSharedPtr<ChLinkEngine> aengine)
{
// store pointer to physical system & other stuff
// so we can tweak them by user keyboard
msystem = asystem;
mdevice = adevice;
mengine = aengine;
}bool MyEventReceiver::OnEvent(const SEvent& event)
{
// check if user moved the sliders with mouse..
if (event.EventType == EET_GUI_EVENT)
{
s32 id = event.GUIEvent.Caller->getID();
IGUIEnvironment* env = mdevice->getGUIEnvironment();

switch(event.GUIEvent.EventType)
{
case EGET_SCROLL_BAR_CHANGED:
if (id == 101) // id of 'engine speed' gui
{
s32 pos = ((IGUIScrollBar*)event.GUIEvent.Caller)->getPos();
double newspeed = 10*(double)pos/100.0;

// set the speed into engine object
ChFunction_Const *spe_funct = dynamic_cast <ChFunction_Const*> (mengine->Get_spe_funct());
spe_funct->Set_yconst(newspeed);// show speed as formatted text in interface screen
char message[50]; sprintf(message,"Engine speed: %g [rad/s]",newspeed);
text_enginespeed->setText(core::stringw(message).c_str());

}
break;
}

}

return false;
}void MyEventReceiver::setText_enginespeed(IGUIStaticText* _text_enginespeed)
{
text_enginespeed = _text_enginespeed;
}IGUIStaticText* MyEventReceiver::getText_enginespeed()
{
return text_enginespeed;
}

и основной файл в Main_2.cpp (который я опустошил, он дает мне ту же ошибку с кодом внутри или без него — который в основном только настраивает 3D-движок Irrlicht и некоторые механические функции из коллизионной модели chrono :: engine)

#include "MyEventReceiver.h"
int main()
{
return 0;
}

В основном, код определяет приемник событий, так что пользователь после запуска программы может взаимодействовать с трехмерной средой, созданной из chrono :: engine и Irrlicht engine, посредством манипулирования GUI.
Я определяю все необходимые библиотеки в файле MyEventReceiver.h и необходимые пространства имен

Проблема в том, что он не компилируется (обратите внимание, что я уже тестировал движки — с тем же #include и используя пространства имен только в одном файле, и он работал в другом проекте -), я думаю, что проблема исходит из структуры заголовочных файлов

Я получил эти строки ошибок

1>MyEventReceiver.obj : error LNK2005: "public: virtual bool __thiscall irr::scene::RTSCamera::OnEvent(struct irr::SEvent const &)" (?OnEvent@RTSCamera@scene@irr@@UAE_NABUSEvent@3@@Z) already defined in Main_2.obj
1>MyEventReceiver.obj : error LNK2005: "public: virtual void __thiscall irr::scene::RTSCamera::OnRegisterSceneNode(void)" (?OnRegisterSceneNode@RTSCamera@scene@irr@@UAEXXZ) already defined in Main_2.obj

и т. д … (так продолжается)
и последняя ошибка

1>C:\Users\****\Documents\Visual Studio 2010\Projects\TutorialChronoEngine\Debug\TutorialChronoEngine_2.exe : fatal error LNK1169: one or more multiply defined symbols found

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

большое спасибо
С наилучшими пожеланиями
Винсент

Изменить: если я положу все коды в один файл следующим образом

#include "physics/CHapidll.h"#include "physics/CHsystem.h"#include "irrlicht_interface/CHbodySceneNode.h"#include "irrlicht_interface/CHbodySceneNodeTools.h"#include "irrlicht_interface/CHdisplayTools.h"#include "irrlicht_interface/CHirrWizard.h"
#include <irrlicht.h>// Use the namespace of Chrono

using namespace chrono;

// Use the main namespaces of Irrlicht
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

// Get rid of the command windows that pops up when compiling and running
#ifdef _IRR_WINDOWS_
#pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup")
#endif

IGUIStaticText* text_enginespeed = 0;

class MyEventReceiver : public IEventReceiver
{
public:

MyEventReceiver(ChSystem* asystem,
IrrlichtDevice *adevice,
ChSharedPtr<ChLinkEngine> aengine)
{
// store pointer to physical system & other stuff
// so we can tweak them by user keyboard
msystem = asystem;
mdevice = adevice;
mengine = aengine;
}

bool OnEvent(const SEvent& event)
{

// check if user moved the sliders with mouse..
if (event.EventType == EET_GUI_EVENT)
{
s32 id = event.GUIEvent.Caller->getID();
IGUIEnvironment* env = mdevice->getGUIEnvironment();

switch(event.GUIEvent.EventType)
{
case EGET_SCROLL_BAR_CHANGED:
if (id == 101) // id of 'engine speed' gui
{
s32 pos = ((IGUIScrollBar*)event.GUIEvent.Caller)->getPos();
double newspeed = 10*(double)pos/100.0;

// set the speed into engine object
ChFunction_Const *spe_funct = dynamic_cast <ChFunction_Const*> (mengine->Get_spe_funct());
spe_funct->Set_yconst(newspeed);

// show speed as formatted text in interface screen
char message[50]; sprintf(message,"Engine speed: %g [rad/s]",newspeed);
text_enginespeed->setText(core::stringw(message).c_str());
}
break;
}

}

return false;
}

private:
ChSystem*       msystem;
IrrlichtDevice* mdevice;
ChSharedPtr<ChLinkEngine> mengine;
};int main(int argc, char* argv[])
{

return 0;
}

Таким образом, я избегаю несколько раз определять функции из движка Irrlicht 3D, которые не определены как встроенные. К сожалению, этот способ кодирования может стать очень громоздким, если проект становится большим (необходимо определить все классы, которые полагаются на 3D-движок в одном уникальном файле .cpp), существует ли шаблон проектирования, которому нужно следовать, чтобы можно было избежать множественного определенные объекты с каждым классом, определенным в отдельном файле?

большое спасибо

Лучший

Винсент

0

Решение

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

irr::scene::RTSCamera::OnEvent(struct irr::SEvent const &)
irr::scene::RTSCamera::OnRegisterSceneNode(void)

Скорее всего, здесь происходит то, что эти две функции определены в заголовочном файле, но:

  • Их определение не отображается непосредственно в определении класса (поэтому они не объявляются как встроенные);
  • Их внеклассное определение в заголовочном файле явно не помечено как встроенное.

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

При объединении их компоновщик будет жаловаться, что вы нарушаете ODR (одно правило определения).

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]