Sign in to follow this  
louie999

Multiple definition error

Recommended Posts

louie999    280

This is really starting to annoy me, whenever I "include" my header file in any of my .cpp files then I get this error:

||=== Build: Debug in Game (compiler: GNU GCC Compiler) ===|
obj\Debug\unithandler.o||In function `ZNSs4_Rep10_M_disposeERKSaIcE':|
C:\mingw32\i686-w64-mingw32\include\c++\bits\basic_string.h|245|multiple definition of `Object::ObjectID'|
obj\Debug\main.o:C:\Games\MYGAMES\TotalWar\main.cpp|8|first defined here|
||=== Build failed: 2 error(s), 0 warning(s) (0 minute(s), 2 second(s)) ===|

My header file:

#ifndef UNITHANDLER_HPP
#define UNITHANDLER_HPP

#include <map>
#include <string>
#include <fstream>
#include <SFML/Graphics.hpp>

class DataHandler
{
    public:
        DataHandler();
        void ReadGameData();
};

class Object
{
    public:
        static int ObjectID;
        Object();
        ~Object();
    private:
        int ID = 0;
        int POS_X;
        int POS_Y;
        int HP;
        int DMG;
        std::string DMG_TYPE;
        std::string TYPE;
        float FUEL;
        float AMMO;
        float MOVES;
        int STATUS = 0;

        void SetProperty(std::string property_type, std::string new_value);
        void SetSprite(sf::Sprite sprite);
        void Draw();

        void Move();
        void Attack(int x, int y);
        int GetMoves();
        int GetHP();
};

class ObjectHandler : public Object
{
    public:
        static int ObjectID;
        ObjectHandler();
        void Add();
        void Remove(int id);
    private:
        std::vector<Object*> ActiveObjects;
};

int Object::ObjectID = 0;

ObjectHandler Obj;

void UpdateObjects();

void DrawObjects();
#endif

Help please.

 

Thanks in advance...

Share this post


Link to post
Share on other sites
CornyKorn21    624

Your definition of Object::ObjectID should be within a source file. Currently if you include your header file in multiple .cpp files the compiler will generate multiple instances of the ObjectID as you have it currently defined "int Object::ObjectID = 0"

On a side note I'm not entirely certain how the compiler handles two declarations of a static with the same name in a base class and the derived class as well.

Share this post


Link to post
Share on other sites
int Object::ObjectID = 0;

This line needs to go in a .cpp file, not a .h file.

 

Otherwise, every single .cpp that #includes the .h will create its own copy of 'Object::ObjectID', which will define it multiple times (hence "multiple definition" as an error).

 

You can declare variables multiple times, but there must be only one authoritative definition.

The differences between declarations and definitions are subtle, but important thing to learn.

 

Likewise:

ObjectHandler Obj;

This should also be in a .cpp file, and perhaps declared 'extern' in the header, if it truly must be global.

 

[Edit:]

 


 

 

On a side note I'm not entirely certain how the compiler handles two declarations of a static with the same name in a base class and the derived class as well.

 

Good catch, I missed that.

 

The answer is, both are different variables.

One is named Object::ObjectID, and the other is named ObjectHandler::ObjectID. Their namespace (or in this case, their class's name), is part of their actual name. The compiler would probably compile it to something conceptually like: _ZN6object9objectidE and _ZN13objecthandler9objectidE, as the invisible internal name the compiler uses.

 

So that's probably not what the OP intended.

Edited by Servant of the Lord

Share this post


Link to post
Share on other sites
louie999    280

Thanks so much guys! :D, I added:

extern int Object::ObjectID = 0;
extern ObjectHandler obj; 

In the .cpp file and now it doesn't give me errors :D

Though, it gave me a warning.

||=== Build: Debug in TotalWar (compiler: GNU GCC Compiler) ===|
C:\Games\MYGAMES\TotalWar\unithandler.cpp|3|warning: 'ObjectID' initialized and declared 'extern'|
||=== Build finished: 0 error(s), 1 warning(s) (0 minute(s), 2 second(s)) ===|

Should I be worried about that? or no?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this