tags:

views:

1388

answers:

2

I'm having trouble with what is apparently a linker error ("undefined reference") in Eclipse / C++. All the classes shown below compile fine, except for one, PlayGame.cpp, which is giving the "undefined reference" error (also shown below).

Below are the relevant classes and pieces of code.

PlayerFactory.h

PlayerFactory.cpp

Game.h

Game.cpp

// constructor for game:

Game::Game (const PlayerFactory& factory)

{

       cout << " constructor" << endl;

}

PlayGame.cpp

// start of code for game where error occurs

#include "Game.h"

#include "PlayerFactory.h"

int main() {
   try

   {

      PlayerFactory factory;

      Game game (factory);  <== undefined reference error
      ...

The above line gives the error "undefined reference to `Game(PlayerFactory const&)'"

What's causing this error, and how can it be corrected?

+1  A: 

The default visibility for class declarations is private. So all the member functions of both Player and PlayerFactory classes are private -- not accessible by clients. You need to make them public.

Player.h

#ifndef PLAYER_H 
#define PLAYER_H
class Player  
{  
public:
   virtual ~Player() {  
       cout << "Player destructor called" << endl;  

   }  
   virtual void Player::PlayerMakeMove(){  
       cout << "make move" << endl;  
   }  


};  
#endif // PLAYER_H

PlayerFactory.h

#ifndef PLAYERFACTORY_H
#define PLAYERFACTORY_H
class PlayerFactory  
{  
public:
   virtual ~PlayerFactory() {  
       cout << "PlayerFactory destructor called" << endl;  
   }  

   virtual std::auto_ptr<Player> PlayerFactory::MakePlayerX() const{  

       return PlayerFactory::MakePlayer('x');  
   }  

   virtual std::auto_ptr<Player> PlayerFactory::MakePlayerO() const{  
       return PlayerFactory::MakePlayer('o');  

   }  

   std::auto_ptr<Player> PlayerFactory::MakePlayer (char letter) const{  
       auto_ptr<Player> pt( new Player() );  
       return pt;  
   }  
};
#endif // PLAYERFACTORY_H

Also, the Game::Play() lacks a return statement.

Outcome Game::Play() {  
  cout << " play" << endl;  
  return PlayerXWon;
}

Do add the required headers, forward declarations and using statements as required (I skip them here).

dirkgently
Not specifically. That is, it's a managed make project. Is this something I need to do? If so, any idea how? Thx.
Jack BeNimble
Are all the cpp files mentioned in the makefile target? Or, even a *.cpp action would do. Just confirm that an obj file corresponding to PlayerFactory is being created and that obj is linked to your main executable.
dirkgently
I just poked around in the makefile, but it's all auto-generated boilerplate code referring to object variables. From googling, it looks like Eclipse automatically includes source files in the make, if you use the managed make option. I've had good luck with it up till now.
Jack BeNimble
Can you print out a list of compiler and/or linker dependencies? I'm guessing there'll be some Eclipse IDE setting to turn that on -- check that.
dirkgently
The compiler allows you to specify a -I option (currently blank). and there's a -c -fmessage-length=0The linker specifies g++ w/ no options but has make variable. You can specify library and library search path, empty now. Misc (linker flags ) is empty. Shared library settings is empty. Thanks for checking. I might try a manual make.
Jack BeNimble
Try this on the command line:g++ -o testapp Game.cpp PlayerFactory.cpp PlayGame.cpp
dirkgently
When I try that, it gives me pretty much the same error messages, i.e. anything on "Game" is undefined. It also adds a couple, saying the reference to the vtable for the destructor and constructor of PlayerFactory is undefined. No idea why - PlayerFactory declares virtual methods in the header, and I define them in the .cpp. The constructor is undeclared and therefore default. The destructor is declared virtual, but I don't have it defined in my subclass. All objects created a .o previously.
Jack BeNimble
We need to see your class declarations at the least.
dirkgently
A: 

Well, for whatever reason, the linker doesn't find the implementation of the constructor, which strongly suggests that it doesn't get compiled.

A Few debugging steps:

  • try to find the .obj files that get generated by gcc. See if you can find Game.obj among them.

  • Find a way to get the IDE to output the command line it generates for gcc

  • if there's no straightforward way, there's always:

    • Make a script, replace gcc with it, and make the script write the commandline into a file and examine that.
AndreasT