Archived

This topic is now archived and is closed to further replies.

C++ linking errors

This topic is 5094 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Keep getting annoying linking errors, and i cant work out what the last thing i did was ! --------------------Configuration: task3 - Win32 Debug-------------------- Compiling... main.cpp Linking... main.obj : error LNK2005: "public: void __thiscall Weapon::fireme(void)" (?fireme@Weapon@@QAEXXZ) already defined in char.obj main.obj : error LNK2005: "public: void __thiscall Weapon::useme(void)" (?useme@Weapon@@QAEXXZ) already defined in char.obj main.obj : error LNK2005: "public: __thiscall NPC::NPC(void)" (??0NPC@@QAE@XZ) already defined in char.obj Debug/task3.exe : fatal error LNK1169: one or more multiply defined symbols found Error executing link.exe. task3.exe - 4 error(s), 0 warning(s) Anyone have any suggestions ? This the full code for the file i think my problem lies in. #ifndef CHAR_H #define CHAR_H #include <iostream> using namespace std; // ============================================================= // BASIC Weapon class // ============================================================= class Weapon { public: // No constructor // Accessor methods void fireme(); // Fires the gun void useme(); // I have decided that using a gun, really means hitting someone // over the head with it. Otherwise whats the difference between // fire and use ?? int GetWeaponAccuracy() { return m_iWeaponAccuracy; } // Gets private details protected: // private details string m_sName; // Name of weapon int m_iAmmo; // Amount of ammo float m_iWeaponAccuracy; // How accurate is the weapon? }; // ============================================================= // Weapons Accessor methods // ============================================================= // FIRE void Weapon::fireme() { if (m_iAmmo == 0) { cout << "Out of ammo" << endl; return; } cout << "Bang, the weapon has fired" << endl; m_iAmmo--; return; } // USE void Weapon::useme() { cout << "Smack, you just hit someone round the head with your weapon" << endl; return; } // ============================================================= // AK47 of type Weapon // ============================================================= class AK47 : public Weapon { public: AK47(){ m_iAmmo=7;m_iWeaponAccuracy=0.3f;m_sName = "Desert Eagle";return;} }; // ============================================================= // Pistol of type Weapon // ============================================================= class Pistol : public Weapon { public: Pistol(){ m_iAmmo=30;m_iWeaponAccuracy=0.8f;m_sName = "AK47";return;} }; // ============================================================= // Character class // ============================================================= class CCharacter { public: // No Constuctors // Accessor methods void fireweapon(); void useweapon(); protected: Weapon* Weapon; // Weapon currently held string m_sName; // Characters name char m_cGender; // M = Male, F = Female, N = Neutral. float m_fAccurate; // How accurate the character is with current gun. // Changes depending on the gun. }; // ============================================================= // None player character class // ============================================================= class NPC : public CCharacter { public: // Constuctor NPC(); // Accessor methods private: float m_fAttackSkill; // How skilled the NPC is when attacking. float m_fAimSkill; // Skill when aiming, a value between 0 and 1. }; // ============================================================= // NPC methods // ============================================================= NPC::NPC() { // Giving him a gun Weapon = new AK47; // Setting default values for the character m_sName = "Default NPC Character"; m_cGender = ''M''; // m_fAccurate Muh m_fAttackSkill = 0.5; m_fAimSkill = 0.5; } #endif

Share this post


Link to post
Share on other sites
Just "remote sensing" here, so I''m not sure if that''s the problem, but:

fireme() is defined in char.h, and not marked as inline. That means every single time you include char.h, the compiled file (.obj) will contain a copy of Weapon::fireme(). The linker then does not know which copy to take.

You can mark it as inline, or you can simply move it to char.cpp, and that solves that problem. The same is true for useme, and NPC::NPC too.

(I personally think you should *never* make anything inline unless there''s a provable need - i.e. you profiled)

As for the "I don''t know what I did", I strongly recommend you use a version control system, such as perforce (www.perforce.com, free personal version) or cvs. That would allow you to simply diff against the last checked-in state and find out what happened.

Hope this helps,
- Robert

Share this post


Link to post
Share on other sites
Either put the definition of the function in the class (don't worry about inline)

Or put it in a separate cpp file (which is the normal way of doing things)

At the moment, every cpp file that includes the header will have the definition of the function compiled into its object file (eg char.obj). When it comes to linking, more than one object file will contain the definition (eg main.obj and char.obj). That's your error.

[edited by - petewood on January 7, 2004 11:11:23 AM]

Share this post


Link to post
Share on other sites
Cheers for the reply folks, I found out what the problem was.

Very simple, i was trying to place my accessor methods implementation inside my .h file, instead of the .cpp file where it should be.

Dam me, i was learning templates a few hours ago and it over rode what should have been second nature. lol.

Cheers for the replies Big slap for me

Share this post


Link to post
Share on other sites