Linker Errors - Unresolved external symbol - c++

Howdy. I am working on a C++ assignment for my class. I am almost done but can't seem to figure out these errors:
error LNK2001: unresolved external symbol "public: virtual void __thiscall HasQuarterState::dispense(void)const " (?dispense#HasQuarterState##UBEXXZ) gumball.obj Gumball
error LNK2001: unresolved external symbol "public: virtual void __thiscall SoldState::turnCrank(void)const " (?turnCrank#SoldState##UBEXXZ) gumball.obj Gumball
fatal error LNK1120: 2 unresolved externals C:\School Work\CS 492\Gumball\Debug\Gumball.exe Gumball
I went to MSDN and looked up LNK2001 error, but was provided with an overwhelming amount of info, and am afraid I can't figure out what is wrong given my limited experience with C++ from looking at the MSDN page.
But I do believe that the problems come from the way I have structured my program. My teacher said we may use one .cpp file if we wanted too, but I guess in the end I didn't know enough about Visual Studios/C++ to make this work. Ultimately I ran into some other problems that I had to solve that came from using one .cpp file.
The code/file in question is here: http://codepad.org/LpBeJT2Y
Its a big ole mess but this is what I have done:
Declare a class named GumballMachine (no definition)
Define a class named State (which in turn has a pointer to a GumballMachine)
Defined several other state classes which inherit from State
Define class GumballMachine
Defined several functions that were excluded from the original definitions of the other state classes. This is because these functions relied on defined functions of GumbballMachine and wouldn't work until the GumballMachine functions were defined.
void main()
As far as I can tell (with my limited knowledge of VS/C++), the code looks to be fine. Maybe there is something someone with more experience would catch. Any pointers on how to knock out this problem?
Thanks for the help.

You've declared dispense in HasQuarterState but have not defined it. The function has no body. Likewise with turnCrank in SoldState.

In class SoldState, turnCrank is not defined. Change this:
void turnCrank() const;
To this:
void turnCrank() const { cout << "some implementation" << endl; }
and similarly for the other function.

Related

How do you read MSVC C++ Linkage Errors

Can Someone explain to me how to read MSVC linkage errors in general.
An example is one I have just hit which I know means that somewhere in my code I am attempting to link something dynamically that isn't there.
What I would like to understand is how to read the error message properly so I can work out exactly which module I have left a dllimport on in.
Error LNK2019 unresolved external symbol "__declspec(dllimport) public: enum SILLY::PixelFormat __cdecl SILLY::Image::getSourcePixelFormat(void)const " (__imp_?getSourcePixelFormat#Image#SILLY##QEBA?AW4PixelFormat#2#XZ) referenced in function "public: virtual class CEGUI::Texture * __cdecl CEGUI::SILLYImageCodec::load(class CEGUI::RawDataContainer const &,class CEGUI::Texture *)" (?load#SILLYImageCodec#CEGUI##UEAAPEAVTexture#2#AEBVRawDataContainer#2#PEAV32##Z) helloworldui C:\Users\XXXXXX\Documents\Audio Development\evil-sounds\build\helloworldui\cegui64sd.lib(ImageCodec.cpp.obj) 1
I think it means that CEGUI::SILLYImageCodec::load is trying to load SILLY:Image::getSourcePixelFormat as a dll when I want it to load a static library.
The load#SILLYImageCodec#CEGUI##UEAAPEAVTexture#2#AEBVRawDataContainer#2#PEAV32##Z bit is throwing me off - it seems backwards.
It means the function SILLY::Image::getSourcePixelFormat called (or otherwise referenced) in the function CEGUI::SILLYImageCodec::load cannot be found by the linker.
The error has little to do with the static vs. import library, it can't be found in any library it has looked in. If it can't be found the linker will produce the same error irrespective of where you intended the function to be. You get the error because you have probably not supplied the linker with the library you want it to use (from what you say, this is the likely error, but it could be caused by a whole host of reasons; see here for more).
The name mangling can be cumbersome, unless you want to write a name demangler, you can generally ignore it (look for the pretty print names instead).
The bit with all the '#' signs is the mangled name. You can generally ignore this as the linker has already demangled it for you. It looks like the dllimport is attached to the SILLY::Image class, probably in the form of a macro between 'class' and the class name.

unresolved external symbol with no "referenced in" field

So, usually when you see an Unresolved External Symbol error, the linker at least tells you what function the reference is in, i.e.
unresolved external symbol "class1::function1" **referenced in function "class2::function2"**
But what do you do when you only get the first half? i.e.
unresolved external symbol "class1::function1"
I know where "class1::function1" is defined, and I am deliberately not including it. So just including the file containing the definition won't help. The include is ifdef'd out, along with all references to symbols contained in the file. What I need is a way to locate the reference to this deliberately non-included symbol so that I can get rid of it. Searches for the name of the symbol reveal only things which I have already ifdef'd out.
If it's a virtual function then it's referenced from the vtable, which in turn is referenced from each constructor (or each place where a constructor is inlined).
If you're using instances of the class I think your best bet is to remove the virtual keyword. Otherwise you must provide a definition, even if only a stub.
(The language standard handles this by considering any virtual function as always used, so a definition is required.)
I'm not sure why that happens, but easy way to determine source of problem is to comment out all declarations of class1::function1, and rebuild the project - compiler will complain whenever class1::function1 is called on compile stage instead of linking.
This turns out to have been a combination of a mistake on my part, and a non-helpful error message. One of the classes was missing a member of it's inheritance chain.
Personally I would have expected this to result in a compiler error ("Extending Undefined Base Class" or something similar), but instead I got linker errors for the virtual functions in said base class (despite that class not being included). But because no functions were actually referencing them, the linker could not provide a "referenced in" section for the error message. I still don't entirely understand why this set of problems with the code gave that set of error messages, but I was able to fix it.
Thank you Alan for your input, it got me looking in the correct direction. I would upvote you, but having joined immediately before posting the question, I lack the reputation score to do so.

Unresolved Externals

I am working on a simple top down shooter and wanted to move my ships to a separate ShipManager class, where I can manage all of them from a single location. However, upon starting this I get a linker error on my playerShip:
error LNK2001: unresolved external symbol "public: static class Ship * ShipManager::playerShip"
ShipManager.h looks like this:
class Ship;
class ShipManager
{
public:
static Ship* playerShip;
};
I have nothing in the ShipManager .cpp yet. What am I missing? The only other place I use this code is in my game class where I am actually calling ShipManager::playerShip, and I don't get any errors there.
I include "ShipManager.h" in my game.cpp, so it should find it right? I have a feeling I'm forgetting something simple in this class.
Static members have to be defined somewhere. You are declaring playerShip, but not defining it. You need to add somewhere, necessarily and only one cpp file:
Ship* ShipManager::playerShip;
You only declared the static member, you also need to define it in (only)one of your cpp files:
Ship* ShipManager::playerShip;
Good Read:
What is the difference between a definition and a declaration?

What is the meaning of error LNK2019

Can Somebody tell me what does the following error implies?
Error 2 error LNK2019: unresolved
external symbol "public: class
TLst & __thiscall
TLst::operator=(class
TLst const &)"
(??4?$TLst#VTInt####QAEAAV0#ABV0##Z)
referenced in function "public: void
__thiscall TPair >::GetVal(class TInt
&,class TLst &)const "
(?GetVal#?$TPair#VTInt##V?$TLst#VTInt######QBEXAAVTInt##AAV?$TLst#VTInt#####Z) randomgraph.obj randomgraph
In general, it means that the linker sees a reference to a symbol, but it can't find it anywhere - often due to a missing library or object file.
In this case this happened because you implemented your templated class'es member functions in a .cpp file - they should be implemented in the header.
A template class is a template not a class. When the compiler see you using e.g. vector<int> f; it creates a new class vector<int> from the template vector. In order to create e.g. vector<int>::size() it needs to see the implementation of size() at the point where the template is instantiated - and it can't do that if the implementation of size() isn't in the header file.
You can get around this by explicitly instantiating vector for int - Then the compiler will see the explicit instantiation when it compiles the cpp file. This defeats the purpose of having a template - it'd only be usable for the types you predefine with explicit instantiation. So, short story, always fully implement templates in header files.
Unresolved external symbol means that there's a reference that the linker can't find. It's usually caused by forgetting to add an object file or library to the link step. (Including the header file for a class isn't enough - you also have to add the implementation code.)
This problem is solved. In the template class TLst, the function
TLst TLst::operator=(const TLst&);
was declared but it was not defined.
I had to define the function in my .cpp file. I could have defined it in my header file as well.
Thanks for the replies.
Somnath

Unresolved External Symbol? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is an undefined reference/unresolved external symbol error and how do I fix it?
I am terrible at reading c++ errors, but obviously Unresolved External Symbol means the function I am using isn't defined. The error I am getting is...
1>WorldState.obj : error LNK2001: unresolved external symbol "public: class Brutal::GameObject * __thiscall Brutal::GameObjectManager::createObject<class Player>(class Ogre::Vector3,class Ogre::Quaternion,class Brutal::PropertyList,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (??$createObject#VPlayer###GameObjectManager#Brutal##QAEPAVGameObject#1#VVector3#Ogre##VQuaternion#4#VPropertyList#1#V?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###Z)
1>C:\Users\Brett\Desktop\Factions Online\build\release\client\client.exe : fatal error LNK1120: 1 unresolved externals
This doesn't make any sense as createObject is defined and even comes up appropriately in MSVC when I right click it and click "go to definition"
My code which calls it is...
Brutal::GameObjectManager::getSingletonPtr()->createObject<Player>(Ogre::Vector3::ZERO, Ogre::Quaternion::IDENTITY);
So am I missing something silly?
Since you are using a template function, it's definition has to be visible when you call it. Therefore, because this is a member function, it has to be implemented in the header where you declared it.
Given that it is a template, have you put the implementation in a different file from the header? (You can do this for specific classes you decide to declare you have a template implementation for, known as instantiation).
I am going to extend my previous post as I can put in coding suggestions here more easily than in a comment.
You have a template function called createObject. You might consider "refactoring" this to use a class because it is easier to single this out.
This is sample code so fill in the detail to make it work for your exact example.
class GamePlayerManager
{
public:
// all the other stuff
template< typename T > createObject(/*params */)
{
// implement inline
res = GameObjectFactory<T>::create(/* whatever parameters */);
}
};
I have now singled out object creation into its own class called GameObjectFactory. At some point where Player is visible you can instantiate this template whilst hiding its create() method.
template class GameObjectFactory<Player>;
This is good enough for the compiler to know it needs to look in the implementation for the implementation of this class's functions (it promotes it into a "real" class so you can put the implementation into its .cpp file). Note that this is an instantiation, not a specialisation, so your template GameObjectFactory could still implement whatever functions you want to inline and you would not have to redefine them for your class. This is a good way to "reuse" the common code whilst allowing you to specialise on some of the detail.
It looks like you're not linking to the associated library. You've got the header included, so the compiler isn't complaining, but the linker doesn't know what you're talking about.
Is createObject taking default arguments or is it overloaded ?
If so, are you defining all versions of that function?
In the error message, its showing more parameters for function than in the call.
And If functions is defined in some other library, you have to link it with your application by giving that library as input to Linker in Project settings.