Singletons (class templates and pure virtual functions)

Started by
22 comments, last by L. Spiro 12 years, 6 months ago
Building your project, I get the following errors:

1>------ Rebuild All started: Project: Improved GameState no singleton, Configuration: Debug Win32 ------
1> stdafx.cpp
1> Start_Menu.cpp
1> Improved GameState no singleton.cpp
1> GameStateManager.cpp
1> Generating Code...
1>Start_Menu.obj : error LNK2019: unresolved external symbol "public: __thiscall CStates<class CGameStateManager>::CStates<class CGameStateManager>(void)" (??0?$CStates@VCGameStateManager@@@@QAE@XZ) referenced in function "public: __thiscall CStart_Menu::CStart_Menu(void)" (??0CStart_Menu@@QAE@XZ)
1>Start_Menu.obj : error LNK2019: unresolved external symbol "public: __thiscall CStates<class CGameStateManager>::~CStates<class CGameStateManager>(void)" (??1?$CStates@VCGameStateManager@@@@QAE@XZ) referenced in function "public: __thiscall CStart_Menu::~CStart_Menu(void)" (??1CStart_Menu@@QAE@XZ)
1>C:\...\Improved GameState no singleton\Improved GameState no singleton\Debug\Improved GameState no singleton.exe : fatal error LNK1120: 2 unresolved externals
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========
[/quote]
Indeed, I cannot find implementations of the highlighted functions.

You can fix these errors by implementing these functions inline (remember, this class is a template, refer to my earlier post for more information):

#ifndef _MY_STATES_H
#define _MY_STATES_H
//****************************************************
//Author: Blessing Tsanga
//Purpose: virtual parent for all states
//****************************************************
#define FAST_BOOL unsigned char
template<class xUsers_states>
class CStates
{
public:
CStates(void)
{
}

//BEGIN STATE:
//take message from previus state
virtual FAST_BOOL Enter(xUsers_states*)=0;

//EXECUTE OUR STATE:
//Now lets get things rolling
virtual void Execute(xUsers_states*)=0;

//EXITING STATE:
//Pass message to our successor message (this class id)
virtual CStates<xUsers_states>* Exit(xUsers_states*)=0;

//virtual destructors are needed for pure virtual classes
//its children will handle differently
virtual ~CStates(void)
{
}
};

#endif

Note that I needed to add the virtual keyword to your destructor. Despite the comment, your destructor was not virtual.

Changing that file, results in the following compiler output:

1>------ Rebuild All started: Project: Improved GameState no singleton, Configuration: Debug Win32 ------
1> stdafx.cpp
1> Start_Menu.cpp
1> Improved GameState no singleton.cpp
1> GameStateManager.cpp
1> Generating Code...
1> Improved GameState no singleton.vcxproj -> C:\...\Improved GameState no singleton\Improved GameState no singleton\Debug\Improved GameState no singleton.exe
========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========
[/quote]

You can also remove the constructor entirely (it does nothing) instead of implementing it.

I question the need for the FAST_BOOL type. If you want to use it, at least use a typedef rather than abuse the preprocessor. But I suspect that it isn't any "faster", and only complicates your code.
Advertisement
I had been taking your recommendations, with a being one being to strip down the project, rewrite it in a console window, as you saw. But now I've reached my tether's end and can't not working on it unless somebody can show me the possibly tiny but significant error in it.

Plus having talked to my lecturer, I've been told to give up on it and rewrite it in a simpler way (no templates or singletons) with major criticism being that it was wasting my time. (& sadly im 4 days behind schedule)

But now I've reached my tether's end and can't not working on it unless somebody can show me the possibly tiny but significant error in it.
[/quote]
I believe I have highlighted your error, and suggested a fix.


Plus having talked to my lecturer, I've been told to give up on it and rewrite it in a simpler way (no templates or singletons) with major criticism being that it was wasting my time. (& sadly im 4 days behind schedule)
[/quote]
This is very good advice. When you have some spare time, you should consider coming back to this and solving this problem at some stage.
I agree with the above but I want to point out that this is the type of error that can bite you in the ass no matter what the complexity of your project is, unless you specifically understand it and know how to fix it.
We asked many times for evidence of a “definition” of those functions, and when the project was delivered it was finally discovered that, despite claims to the contrary, there were no “definitions”, only “declarations”.

As I said in my first reply, you need to understand what these terms mean. I was not joking.

For the full details, ask your lecturer, as he or she will be able to answer your questions in real-time as you have them and provide you with sufficient examples.
But the skinny is this:

void MyFunc(); <- It has a semi-colon. It is a “declaration”. Goes in the .H file.

void MyFunc() { <- Braces. This is the “definition”. Typically goes in the .CPP file, but sometimes in the .H.
}


Your problem was caused by the linker. It saw the declaration in your .H file. The declaration simply says that the function exists, somewhere. That’s good enough for the compiler, but the linker has to actually track down the actual function in order to use it. Without the function being “defined”, the linker can’t do this. This is the cause of your errors, and you need to remember this for every project you continue to write, big or small.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

This topic is closed to new replies.

Advertisement