views:

244

answers:

2

I have two classes, one inherited from the other. When I compile, I get the following errors:

Entity.obj : error LNK2019: unresolved external symbol "public: __thiscall Utility::Parsables::Base::Base(void)" (??0Base@Parsables@Utility@@QAE@XZ) referenced in function "public: __thiscall Utility::Parsables::Entity::Entity(void)" (??0Entity@Parsables@Utility@@QAE@XZ)

Entity.obj : error LNK2019: unresolved external symbol "public: virtual __thiscall Utility::Parsables::Base::~Base(void)" (??1Base@Parsables@Utility@@UAE@XZ) referenced in function "public: virtual __thiscall Utility::Parsables::Entity::~Entity(void)" (??1Entity@Parsables@Utility@@UAE@XZ)

D:\Programming\Projects\Caffeine\Debug\Caffeine.exe : fatal error LNK1120: 2 unresolved externals

I really can't figure out what's going on.. can anyone see what I'm doing wrong? I'm using Visual C++ Express 2008. Here are the files..

"include/Utility/Parsables/Base.hpp"

#ifndef CAFFEINE_UTILITY_PARSABLES_BASE_HPP
#define CAFFEINE_UTILITY_PARSABLES_BASE_HPP

namespace Utility
{
 namespace Parsables
 {
  class Base
  {
  public:
   Base( void );
   virtual ~Base( void );
  };
 }
}

#endif //CAFFEINE_UTILITY_PARSABLES_BASE_HPP

"src/Utility/Parsables/Base.cpp"

#include "Utility/Parsables/Base.hpp"

namespace Utility
{
 namespace Parsables
 {
  Base::Base( void )
  {
  }

  Base::~Base( void )
  {
  }
 }
}

"include/Utility/Parsables/Entity.hpp"

#ifndef CAFFEINE_UTILITY_PARSABLES_ENTITY_HPP
#define CAFFEINE_UTILITY_PARSABLES_ENTITY_HPP

#include "Utility/Parsables/Base.hpp"

namespace Utility
{
 namespace Parsables
 {
  class Entity : public Base
  {
  public:
   Entity( void );
   virtual ~Entity( void );
  };
 }
}

#endif //CAFFEINE_UTILITY_PARSABLES_ENTITY_HPP

"src/Utility/Parsables/Entity.cpp"

#include "Utility/Parsables/Entity.hpp"

namespace Utility
{
 namespace Parsables
 {
  Entity::Entity( void )
  {
  }

  Entity::~Entity( void )
  {
  }
 }
}
A: 

The relevant bit is this:

unresolved external symbol "public: __thiscall Utility::Parsables::Base::Base(void)"

You need to provide a definition for Base::Base and Base::~Base. A declaration is not good enough. Even if you have nothing to do in either function, you need to leave an empty function body, because C++ actually requires the function to exist. C++ puts things like virtual table maintenance inside your constructors and destructors, so they must be defined even if you don't need to do anything there -- C++ has to do things in there.

Are you sure Base.cpp is being included in the build?

Billy ONeal
My source files do have definitions in them, I left an empty function body as you've described.
BLH
@BLH: Read my last sentence again :) (I edited the answer even though it doesn't appear that way)
Billy ONeal
I just checked and remembered something, I have two files both named Base.cpp, but they are in different directories. I see one compile, but not two. Could that be the problem?
BLH
@BLH: Yes, that would do it. AFAIK by default VS dumps it's object files into a single directory, each file named after the source file that gave rise to it. It's possible then for one to overwrite the other.
Billy ONeal
That makes sense. Is there any way around it or am I just going to have to rename one of them?
BLH
@BLH: In project properties: Configuration Properties -> C/C++ -> Output Files -> Object File Name. You should be able to change it there from $(IntDir) to something like $(SourceFilePath)\${SourceFileName}.obj\, though I have not tried this.
Billy ONeal
OK, thanks for the help, much appreciated ;)
BLH
@BLH Best not to have complex directory structures (or complex namespace schemes) - they will always cause trouble, particularly when porting code.
anon
A: 

Either your base.cpp is not being compiled/linked or you have a misspelling in it

Chris Hafey