Need Help With LNK2005 Error

This is a discussion on Need Help With LNK2005 Error within the C++ Programming forums, part of the General Programming Boards category; I have a couple classes inside one of my header files which I need to access in two different .cpp ...

  1. #1
    Registered User
    Join Date
    Mar 2011
    Posts
    61

    Need Help With LNK2005 Error

    I have a couple classes inside one of my header files which I need to access in two different .cpp files, so I tried to include the .h file in both. One of the class declarations looks like this:

    Code:
    class GamePlayers
    {
    public:
    	GamePlayers();
    	void AssignCard(CardTypes Card);
    	void AssignPosition(PositionTypes Position);
    private:
    	CardTypes Hand[14];
    	PlayerTypes PlayerID;
    	PositionTypes Position;
    	bool Human;
    	int Score;
    } Player1, Player2, Player3, Player4;
    Now when I try to compile I get the following linker error for every member of either class:

    Graphics.obj : error LNK2005: "class GamePlayers Player1" (?Player1@@3VGamePlayers@@A) already defined in Gameplay.obj
    What do I need to do to fix this problem?

  2. #2
    Registered User manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    Kolkata@India
    Posts
    2,498
    Use Header Guards .
    Manasij Mukherjee | gcc-4.8.2 @Arch Linux
    Slow and Steady wins the race... if and only if :
    1.None of the other participants are fast and steady.
    2.The fast and unsteady suddenly falls asleep while running !



  3. #3
    Registered User
    Join Date
    Mar 2011
    Posts
    61
    Quote Originally Posted by manasij7479 View Post
    Use Header Guards .
    Meaning???

    EDIT: If you mean #ifndef/#define at the beginning of the header file and #endif at the end, I've already done that.
    Last edited by LyTning94; 07-13-2011 at 09:53 AM.

  4. #4
    a_capitalist_story
    Join Date
    Dec 2007
    Posts
    2,652
    Show us the header file containing the GamePlayer class in its entirety.

  5. #5
    Registered User manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    Kolkata@India
    Posts
    2,498
    Quote Originally Posted by LyTning94 View Post
    Meaning???

    EDIT: If you mean #ifndef/#define at the beginning of the header file and #endif at the end, I've already done that.
    In that case... are you sure that Player1, Player2, Player3, Player4 are supposed to be global variables ?
    Also, as your error message seems to suggest, try separating the different classes and sections of the code into namespaces.


    *As 'rags_to_riches' said , posting some more code would be a good idea *
    Manasij Mukherjee | gcc-4.8.2 @Arch Linux
    Slow and Steady wins the race... if and only if :
    1.None of the other participants are fast and steady.
    2.The fast and unsteady suddenly falls asleep while running !



  6. #6
    Registered User
    Join Date
    May 2009
    Posts
    2,745
    A C programmer guess at solution.
    Removed the Global Player1, Player2, Player3, Player4
    By changing
    Code:
    } Player1, Player2, Player3, Player4;
    to
    Code:
    }
    Tim S.

  7. #7
    Registered User
    Join Date
    Mar 2011
    Posts
    61
    Quote Originally Posted by manasij7479 View Post
    In that case... are you sure that Player1, Player2, Player3, Player4 are supposed to be global variables ?
    I need them to be global variables, if that's what you're asking.

    Quote Originally Posted by manasij7479 View Post
    Also, as your error message seems to suggest, try separating the different classes and sections of the code into namespaces.
    Sorry for my ignorance, but what does that mean?

    At any rate, here's my header file as requested:

    Code:
    #ifndef GAMEPLAY_H
    #define GAMEPLAY_H
    
    #include "SDL.h"
    
    enum PlayerTypes
    {
    	PLAYER_1,
    	PLAYER_2,
    	PLAYER_3,
    	PLAYER_4
    };
    
    enum PositionTypes
    {
    	NO_POSITION = -1,
    	POSITION_1,
    	POSITION_2,
    	POSITION_3,
    	POSITION_4
    };
    
    enum CardTypes
    {
    	NO_CARD = -1,
    	SPADES_ACE,
    	SPADES_2,
    	SPADES_3,
    	SPADES_4,
    	SPADES_5,
    	SPADES_6,
    	SPADES_7,
    	SPADES_8,
    	SPADES_9,
    	SPADES_10,
    	SPADES_JACK,
    	SPADES_QUEEN,
    	SPADES_KING,
    	DIAMONDS_ACE,
    	DIAMONDS_2,
    	DIAMONDS_3,
    	DIAMONDS_4,
    	DIAMONDS_5,
    	DIAMONDS_6,
    	DIAMONDS_7,
    	DIAMONDS_8,
    	DIAMONDS_9,
    	DIAMONDS_10,
    	DIAMONDS_JACK,
    	DIAMONDS_QUEEN,
    	DIAMONDS_KING,
    	CLUBS_ACE,
    	CLUBS_2,
    	CLUBS_3,
    	CLUBS_4,
    	CLUBS_5,
    	CLUBS_6,
    	CLUBS_7,
    	CLUBS_8,
    	CLUBS_9,
    	CLUBS_10,
    	CLUBS_JACK,
    	CLUBS_QUEEN,
    	CLUBS_KING,
    	HEARTS_ACE,
    	HEARTS_2,
    	HEARTS_3,
    	HEARTS_4,
    	HEARTS_5,
    	HEARTS_6,
    	HEARTS_7,
    	HEARTS_8,
    	HEARTS_9,
    	HEARTS_10,
    	HEARTS_JACK,
    	HEARTS_QUEEN,
    	HEARTS_KING,
    	RED_JOKER,
    	BLACK_JOKER
    };
    
    class GamePlayers
    {
    public:
    	GamePlayers();
    	void AssignCard(CardTypes Card);
    	void AssignPosition(PositionTypes Position);
    private:
    	CardTypes Hand[14];
    	PlayerTypes PlayerID;
    	PositionTypes Position;
    	bool Human;
    	int Score;
    } Player1, Player2, Player3, Player4;
    
    class Cards
    {
    public:
    	Cards();
    	void ApplyCard(int X, int Y);
    private:
    	SDL_Rect Clip;
    	CardTypes CardID;
    	PlayerTypes Owner;
    	int Value;
    } BlackJoker, RedJoker, SpadesTwo, DiamondsTwo, ClubsTwo, HeartsTwo,
    	SpadesAce, DiamondsAce, ClubsAce, HeartsAce, SpadesKing, DiamondsKing, ClubsKing, HeartsKing,
    	SpadesQueen, DiamondsQueen, ClubsQueen, HeartsQueen, SpadesJack, DiamondsJack, ClubsJack, HeartsJack,
    	SpadesTen, DiamondsTen, ClubsTen, HeartsTen, SpadesNine, DiamondsNine, ClubsNine, HeartsNine,
    	SpadesEight, DiamondsEight, ClubsEight, HeartsEight, SpadesSeven, DiamondsSeven, ClubsSeven, HeartsSeven,
    	SpadesSix, DiamondsSix, ClubsSix, HeartsSix, SpadesFive, DiamondsFive, ClubsFive, HeartsFive,
    	SpadesFour, DiamondsFour, ClubsFour, HeartsFour, SpadesThree, DiamondsThree, ClubsThree, HeartsThree;
    
    static PlayerTypes Dealer = PLAYER_1;
    
    GamePlayers* GetPlayer(PlayerTypes PlayerID);
    Cards* GetCard(CardTypes CardID);
    
    #endif

  8. #8
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    You don't define global variables in a header file. You declare them extern in the header file, and then in one (and only one) source file you define them.

  9. #9
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,806
    Code:
    class GamePlayers
    {
    public:
    	GamePlayers();
    	void AssignCard(CardTypes Card);
    	void AssignPosition(PositionTypes Position);
    private:
    	CardTypes Hand[14];
    	PlayerTypes PlayerID;
    	PositionTypes Position;
    	bool Human;
    	int Score;
    } Player1, Player2, Player3, Player4;
    When you have something like the above in a header file it causes problems if that header file is #include'd in more than one object file. Each individual object file, when compiled, gets their own copies of the variables Player1, Player2, Player3, Player4. This works fine in the compilation stage but when it comes time for the linker to create the final executable it does so by merging the code for all the separate object files. Since each object file has a copy of the variables in question the linker barfs and says you've already got something in one object file that's been defined in another. You'll get this error for any and all variables (except static?) you've managed to create in the header.

    If you need to access the same object/variable in multiple source files, do what tabstop mentioned. Making them extern in the header will notify each source file that these objects exist (somewhere) and allows code to be written in those source files which uses those items but it will not actually create them. Putting the actual variables themselves in one (and only one) source file makes sure that only one copy exists for those items and makes your linker happy.
    Last edited by hk_mp5kpdw; 07-13-2011 at 11:58 AM.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  10. #10
    Registered User
    Join Date
    Mar 2011
    Posts
    61
    I changed them to extern in the header file and then defined them all in another file as suggested. It works great now. Thanks for the help.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. LNK2005 Linker Error
    By Jonnster in forum Windows Programming
    Replies: 1
    Last Post: 03-29-2011, 09:52 AM
  2. error LNK2005:_**** already defined in main.obj
    By DenJansen in forum C Programming
    Replies: 6
    Last Post: 12-13-2010, 09:44 PM
  3. LNK2005 error (multiple declarations?)
    By maxsthekat in forum C++ Programming
    Replies: 3
    Last Post: 09-10-2009, 05:35 PM
  4. VC++ error LNK2005 (class in extern. file)
    By cminusminus in forum C++ Programming
    Replies: 8
    Last Post: 03-24-2008, 02:20 PM
  5. error LNK2005: _menu already defined in main.obj
    By IndioDoido in forum C Programming
    Replies: 1
    Last Post: 05-17-2007, 12:51 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21