class CommandManager {
public:
void sendText(std::string command);
static bool CommandManager::started;
private:
bool parseCommand(std::string commands);
void changeSpeed(std::vector<std::string> vec);
void help(std::vector<std::string> vec);
};
And here's the client code:
CommandManager::started = true;
Linking these two files together I get:
1>UAlbertaBotModule.obj : error LNK2001: unresolved external symbol "public: static bool CommandManager::started" (?started#CommandManager##2_NA)
1>C:\Development\School\cmput350-uofabot\UAlbertaBot\vs2008\Release\UAlbertaBot.dll : fatal error LNK1120: 1 unresolved externals
Where did I go wrong here?
You're doing that incorrectly.
class CommandManager {
public:
void sendText(std::string command);
static bool started; //NOT this -> bool CommandManager::started
//...
};
then put the definition of static member in .cpp file as:
#include "CommandManager.h" //or whatever it is
bool CommandManager::started = true; //you must do this in .cpp file
Now you can use CommandManager::started in your client code.
You should have inside your class:
class CommandManager {
public:
void sendText(std::string command);
static bool started;
//// etc
};
and outside your class, in a *.cc file (not in a *.hh header file), a definition like
bool CommandManager::started;
BTW, I believe you'll better make that private.
Consider putting
bool CommandManager::started;
where you define other members.
Related
So I am currently working on a basic game engine with a collision system. For that system I have a CollidableGroup template class which objects register themselves too. However, I am not super experienced with templates and am running into an unresolved external error.
The class is a Singleton and the problem is comming from my GetInstance() method which is being called in the register/deregister.
Here is the code:
#ifndef CollidableGroup_
#define CollidableGroup_
#include "ContainerAlias.h"
//#include "Collidable.h"
template<class CollidableType>
class CollidableGroup {
public:
static const KL::CollidableList& GetCollideableCollection() {
GetInstance().PrivateGetColliableCollection();
};
static void Register(CollidableType& collidable_) {
GetInstance().PrivateRegister(collidable_);
};
static void Deregister(CollidableType& collidable_) {
//GetInstance().PrivateDeregister(collidable_)
};
private:
CollidableGroup();
CollidableGroup<CollidableType>(const CollidableGroup<CollidableType>&) = delete;
CollidableGroup<CollidableType>& operator=(const CollidableGroup<CollidableType>&) = delete;
~CollidableGroup() {
instance = nullptr;
};
static CollidableGroup<CollidableType>* instance;
static CollidableGroup<CollidableType>& GetInstance() {
if(!instance)
{
instance = new CollidableGroup<CollidableType>;
}
return *instance;
}
void Delete() {};
KL::CollidableList mCollidableCollection;
void PrivateDeregister(CollidableType&) {};
void PrivateRegister(CollidableType& collideable_) {
mCollidableCollection.insert(mCollidableCollection.end(), &collideable_);
};
const KL::CollidableList& PrivateGetColliableCollection() {
return mCollideablCollection;
};
};
template <typename CollidableType>
CollidableGroup<CollidableType>* CollidableGroup<CollidableType>::instance = nullptr;
//template<class CollidableType>
//inline void CollidableGroup<CollidableType>::Register(CollidableType & /*collidable_*/) {
// GetInstance();// .PrivateRegister(collidable_);
//};
#endif //!CollidableGroup_
ERROR:
1>------ Build started: Project: KatanaEngine, Configuration: Debug Win32 ------
1>Tank.cpp
1>Tank.obj : error LNK2019: unresolved external symbol "private: __thiscall CollidableGroup<class Tank>::CollidableGroup<class Tank>(void)" (??0?$CollidableGroup#VTank####AAE#XZ) referenced in function "private: static class CollidableGroup<class Tank> & __cdecl CollidableGroup<class Tank>::GetInstance(void)" (?GetInstance#?$CollidableGroup#VTank####CAAAV1#XZ)
1>C:\Users\David_Desktop\Perforce\dklimavi_DESKTOP\berthiaume2018winter_gam374\student\dklimavi\Sprint_6\katanaenginerep\KatanaEngine\Debug\KatanaEngine_Debug.exe : fatal error LNK1120: 1 unresolved externals
1>Done building project "KatanaEngine.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
mostly what #drescherjm said, you declared a constructor, but the implementation isn't in your template definition, in the .h
CollidableGroup();
You should at least do something like this:
CollidableGroup() = default;
or
CollidableGroup() {};
if you implemented it in the .cpp, it won't work. You need to write the implementation in the h file when you work with template.
Hope some one could help me with this very trivial error which I have not idea how to proceed :)
Here's the header file:
#ifndef __InputHandler__
#define __InputHandler__
#include "SDL.h"
#include <SDL_image.h>
#include <vector>
#include <iostream>
enum mouse_buttons {
LEFT = 0,
MIDDLE = 1,
RIGHT = 2,
};
class InputHandler {
public:
bool getMouseButtonState(int buttonNumber) {
return m_mouseButtonStates[buttonNumber];
}
std::vector<bool> m_mouseButtonStates;
static InputHandler* Instance() {
if (s_pInstance == 0) {
s_pInstance = new InputHandler();
}
return s_pInstance;
}
void update();
void clean();
private:
InputHandler();
~InputHandler() {}
static InputHandler* s_pInstance;
};
#endif
And I call the InputHandler::Instance() function in another class definition Player.cpp
#include "InputHandler.h"
void Player::handleInput() {
if (InputHandler::Instance()->getMouseButtonState(LEFT)) {
m_velocity.setX(1);
}
}
Here's the error that I get:
Player.obj : error LNK2001: unresolved external symbol
"private: static class InputHandler * InputHandler::s_pInstance"
I honestly don't know what's going on and what the error is pointing to. REALLY REALLY appreciate your wisdom :)))
"I honestly don't know what's going on and what the error is pointing to. "
The linker error message pretty much tells you what's missing.
The current problem you have, is you're missing a definition for the static InputHandler* s_pInstance; member in a translation unit. It should look like this:
InputHandler* InputHandler::s_pInstance = 0;
Though your approach to the singleton pattern has some flaws and deficiencies (especially regarding thread safety). You should simplify your singleton pattern like this:
static InputHandler& Instance() {
static InputHandler theInputHandler;
return theInputHandler;
}
or if you insist using a a pointer
static InputHandler* Instance() {
static InputHandler theInputHandler;
return &theInputHandler;
}
This is commonly known as 'Scott Meyer's Singleton idiom', here's some more information about the original reasonings;
C++ and the Perils of Double-Checked Locking
The error occurred when I called a constructor of a derived class in another project. I omitted some details in the code. I am using Visual Studio 2012.
-Base/derived classes and the test file are in two different projects. Base/derived classes can be compiled without problems.
-The Test project can be compiled successfully when comment the constructor line.
-Test.cpp plays well with other constructor in the DerivationFunction file.
// Test.cpp
#include "DerivationFunction.h"
Child con(123, 123); // error LNK2019: unresolved external symbol "public: __thiscall Child::Child(unsigned short,unsigned int)" (??Child##QAE#GI#Z) referenced in function _main
The header file of base class and derived class:
// DerivationFunction.h
class Base
{
public:
virtual void AppendEnums() = 0;
static int CopyBuffer();
uint16 GetFeatureID();
protected:
uint16 baseValue;
static int Copy();
};
// Child class
class Child : public Base
{
public:
uint32 childValue;
Child(uint16 featureID, uint32 value);
void AppendEnums();
};
The source file:
// DerivationFunction.cpp
int Base::CopyBuffer()
{
return 0;
}
uint16 Base::GetFeatureID()
{
return baseValue;
}
int Base::Copy()
{
return 0;
}
// Child class
Child::Child(uint16 featureID, uint32 value)
{
baseValue = featureID;
childValue = value;
}
void Child::AppendEnums()
{
}
The simplest answer is that you haven't built and included the implementation file in with your main and hence the linker cannot find the code for the Child constructor. Look in the MSDN help for that particular error code and check all of the possibilities there.
If you want to use these classes in another project then you either include the whole sources (headers and cpp files) and build them, or export them from a DLL project and import them in the other project(s).
I've recently started to program in C++ again, and for the purposes of education, I am working on creating a poker game. The weird part is, I keep getting the following error:
1>LearningLanguage01.obj : error LNK2019: unresolved external symbol "public: __thiscall PokerGame::Poker::Poker(void)" (??0Poker#PokerGame##QAE#XZ) referenced in function "void __cdecl `dynamic initializer for 'pokerGame''(void)" (??__EpokerGame##YAXXZ)
1>LearningLanguage01.obj : error LNK2019: unresolved external symbol "public: __thiscall PokerGame::Poker::~Poker(void)" (??1Poker#PokerGame##QAE#XZ) referenced in function "void __cdecl `dynamic atexit destructor for 'pokerGame''(void)" (??__FpokerGame##YAXXZ)
1>LearningLanguage01.obj : error LNK2019: unresolved external symbol "public: void __thiscall PokerGame::Poker::begin(void)" (?begin#Poker#PokerGame##QAEXXZ) referenced in function _wmain
1>C:\Visual Studio 2012\Projects\LearningLanguage01\Debug\LearningLanguage01.exe : fatal error LNK1120: 3 unresolved externals
I have done some research on the issue, and most point to the constructor and destructor definition in the header and .cpp not matching. I don't see any issues with the header and .cpp.
Here is the code for poker.h:
#pragma once
#include "Deck.h"
using namespace CardDeck;
namespace PokerGame
{
const int MAX_HAND_SIZE = 5;
struct HAND
{
public:
CARD cards[MAX_HAND_SIZE];
};
class Poker
{
public:
Poker(void);
~Poker(void);
HAND drawHand(int gameMode);
void begin();
};
}
And the code in the .cpp:
#include "stdafx.h"
#include "Poker.h"
using namespace PokerGame;
const int TEXAS_HOLDEM = 0;
const int FIVE_CARD = 1;
class Poker
{
private:
Deck deck;
Poker::Poker()
{
deck = Deck();
}
Poker::~Poker()
{
}
void Poker::begin()
{
deck.shuffle();
}
//Draws a hand of cards and returns it to the player
HAND Poker::drawHand(int gameMode)
{
HAND hand;
if(gameMode == TEXAS_HOLDEM)
{
for(int i = 0; i < sizeof(hand.cards); i++)
{
hand.cards[i] = deck.drawCard();
}
}
return hand;
}
};
Because of the comment below, I've rewritten what I had before.
The problem that the linker is complaining about is that you've declared your member functions in Poker, but haven't defined them. How is this? For starters, you're creating a new class and defining separate member functions in it.
Your header file Poker class exists in the PokerGame namespace and your cpp file Poker class exists in the global namespace. To fix that issue, put them in the same namespace:
//cpp file
namespace PokerGame {
class Poker {
...
};
}
Now that they're in the same namespace, you have another issue. You're defining your member functions inside the class body, but not the first one. The definitions simply can't go in the body of a class named the same way. Get rid of the whole class in the cpp file:
//cpp file
namespace PokerGame {
Poker::Poker() {
deck = Deck(); //consider a member initializer instead
}
//other definitions
}
One last thing: you put the private section of your class in the wrong spot. It was in that cpp file class that we just removed. It belongs with the other parts of your class:
//header file
namespace PokerGame {
class Poker {
public:
//public stuff
private:
Deck deck; //moved from cpp file
};
}
Another solution could be: check the cmake file and make sure it (such as in ADD_EXECUTABLE) includes the .cpp file you listed.
I'm getting a linker error using CString the error is:
error LNK2001: unresolved external symbol "private: static class ATL::CStringT<wchar_t,class StrTraitMFC<wchar_t,class ATL::ChTraitsCRT<wchar_t> > > CConfiguration::_campaignFolderPath" (?_campaignFolderPath#CConfiguration##0V?$CStringT#_WV?$StrTraitMFC#_WV?$ChTraitsCRT#_W#ATL#####ATL##A)
I have a class which is defined as:
class CConfiguration
{
private:
static CString _campaignFolderPath;
public:
static void Read();
private:
CConfiguration(void);
~CConfiguration(void);
};
Its Read method is defined as:
void CConfiguration::Read()
{
CConfigFile configReader(_T("Config.ini"));
TCHAR temp[1024];
configReader.GetStringValue(_T("Campaigns"), _T("CampaignsFolderPath"), temp);
_campaignFolderPath = temp;
}
Any clues as to what is causing the error? I'm using Visual Studio 2008
You need to instantiate the string, you're just declaring it as static now. Add:
CString CConfiguration::_campaignFolderPath;
in the implementation file.
Do you have an implementation line like the following somewhere?
CString CConfiguration::_campaignFolderPath;