Singleton Inheritance Linker Error - c++

I'm new with C++, and I got this linker error,
LNK2001: unresolved external symbol "private: static class DebugLog Singleton::instance" (?instance#?$Singleton#VDebugLog####0VDebugLog##A)
And here is the problematic codes:
template<typename T>
class Singleton {
public:
static T& getInstance() {
return instance;
}
private:
static T instance;
};
class DebugLog : public Singleton<DebugLog> {
public:
void doNothing() {}
};
void main() {
DebugLog::getInstance().doNothing();
}
Could anybody tell me how I can fix that linker error without losing the Singleton inheritance in DebugLog?
Thank you.

You missed:
template<typename T>
T Singleton<T>::instance;
Insert those lines after your class definition.
In order to initialize a static data-member we must include a formal
definition outside the class, in the global scope.
For more information read this link (Section: Static members)

You need to actually define an instance of the static variable DebugLog Singleton::instance somewhere in your code, you just declared that it exists somewhere, but never actually created it to really exist. The linker is looking for it.
Here's some examples of how to do it right.

Related

virtual function in template inherited class

I am new to templates and I have searched the web for this error but I don't know how to fix it it.
Already checked Why can templates only be implemented in the header file?
State.h
template <class entityType>
class State
{
public:
State() = default;
virtual void Enter(entityType * owner);
};
EnterMine.h
#include "State.h"
class Miner;
class EnterMine : public State<Miner>
{
public:
EnterMine() = default;
virtual void Enter(Miner *) {
};
};
and Miner.cpp is blank
and the problem appears in main.cpp
#include "EnterMine.h"
int main()
{
EnterMine a;
}
The error I get is a linking error :
LNK2001 unresolved external symbol "public: virtual void __thiscall State::Enter(class Miner *)" (?Enter#?$State#VMiner####UAEXPAVMiner###Z)
(Note: this answer was written for the original question, it has been completely rewritten after that.)
Every function that is declared and used, should be defined somewhere.
It seems that you declare EnterMine::EnterMine() but never define it. If this constructor does nothing, either omit it (it will be implicitly defined by a compiler), or mark it as = default;.
class EnterMine : public State<Miner>
{
public:
EnterMine() = default;
...
};
This also applies to the State::State() constructor.
Even though it's a singleton, you're still calling the constructor. Thus, you will still need to define the constructor.
In fact, you need to define every function you declare in your header.

c++ link error if function is implemented in .cpp

If I implement the create method of the class in .cpp I get
error LNK2019: unresolved external symbol "protected: __thiscall Singleton::Singleton(void)" (??0Singleton##IAE#XZ) referenced in function "public: static void __cdecl Singleton::create(void)" (?create#Singleton##SAXXZ
However if I implement the method inside the header file it compiles without any error :S
header file
#pragma once
#include <iostream>
class Singleton
{
public:
static Singleton * getInstance()
{
return s_instance;
}
static void create();
static void destroy();
void help();
protected:
static Singleton * s_instance;
Singleton();
};
source file:
#include "Singleton.h"
Singleton * Singleton::s_instance = NULL;
void Singleton::create()
{
if (!s_instance)
{
s_instance = new Singleton;
}
}
void Singleton::destroy()
{
delete s_instance;
s_instance = NULL;
}
However If I implement the create method inside the header it does not throws any error
Header file with create method implemented in it
#pragma once
#include <iostream>
class Singleton
{
public:
static Singleton * getInstance()
{
return s_instance;
}
static void create(){
if (!s_instance)
{
s_instance = new Singleton;
}
}
static void destroy();
protected:
static Singleton * s_instance;
Singleton();
};
In cpp, your create function is trying to initialize Singleton, by using new operator, but you dont give it an constructor. Try to give an implementation to Singleton(). i.e.:
protected:
static Singleton * s_instance;
Singleton() {}
};
The problem.
You have declared a default constructor, and you're using it (in a new expression), but you haven't implemented it.
Fix.
Simply remove the constructor declaration:
protected:
static Singleton * s_instance;
// Singleton(); -- don't have this. Remove it.
};
Other matters.
With protected features the class is designed for inheritance, so how does one ensure that a derived class can only be instantiated via the singleton machinery?
Well you don't have much control over derived classes, so the easiest is just to document that each derived class should declare and define a non-public default constructor.
However, there is a trick that can be used to enforce this, based on the fact that a virtual base must be initialized by the most derived class. This can be used to force client code to add a final class derivation at bottom. Where that most derived class is a template instantiation, which defines a non-public constructor.
A more practical alternative is to turn things upside-down.
That is, instead of designing the Singleton class for derivation (signalled by protected stuff), design it to inherit from a client code class. Again this means using templates. Andrei Alexandrescu discussed a number of singleton approaches using this idea, in his classic book “Modern C++ Design”.

Unresolved External Symbol in Singleton Class

I've been coding for a long time now but I do not understand this error. I am writing a custom system for providing unique integer ID's to specific instances of objects (I call them tags). And I am implementing one of the classes as a Singleton.
The two classes for the Tagging system are defined as such:
#include "singleton.h"
class Tag: public bear::Singleton<Tag>
{
public:
static dUINT32 RequestTag(Tagged* requester);
static void RevokeTags(void);
private:
Tag(void);
~Tag(void);
Tagged** m_tagTable; // list of all objects with active tags
dUINT32 m_tagTable_capacity, // the maximum capacity of the tag table
m_tagIndexer; // last given tag
};
class Tagged
{
friend class Tag;
public:
inline dUINT32 GetTag(void) {return m_tag;}
private:
inline void InvalidateTag(void) {m_tag=INVALID_TAG;}
dUINT32 m_tag;
protected:
Tagged();
virtual ~Tagged();
};
The Singleton class is defined as such:
template <typename T>
class Singleton
{
public:
Singleton(void);
virtual ~Singleton(void);
inline static T& GetInstance(void) {return (*m_SingletonInstance);}
private:
// copy constructor not implemented on purpose
// this prevents copying operations any attempt to copy will yield
// a compile time error
Singleton(const Singleton<T>& copyfrom);
protected:
static T* m_SingletonInstance;
};
template <typename T>
Singleton<T>::Singleton (void)
{
ASSERT(!m_SingletonInstance);
m_SingletonInstance=static_cast<T*>(this);
}
template <typename T>
Singleton<T>::~Singleton (void)
{
if (m_SingletonInstance)
m_SingletonInstance= 0;
}
I am getting the following error upon trying to compile and link together the files:
test.obj : error LNK2001: unresolved external symbol "protected: static class util::Tag * bear::Singleton::m_SingletonInstance" (?m_SingletonInstance#?$Singleton#VTag#util###bear##1PAVTag#util##A)
1>C:...\tools\Debug\util.exe : fatal error LNK1120: 1 unresolved externals
Does anyone have any idea why I am getting this error?
You should provide a definition for your static data member at namespace scope (currently, you only have a declaration):
template <typename T>
class Singleton
{
// ...
protected:
static T* m_SingletonInstance; // <== DECLARATION
};
template<typename T>
T* Singleton<T>::m_SingletonInstance = nullptr; // <== DEFINITION
If you are working with C++03, you can replace nullptr with NULL or 0.

C++ shared_ptr based singletone what causes link error?

So I try this code:
#ifndef TRANSMITTER_H
#define TRANSMITTER_H
class connector
{
public:
static boost::shared_ptr<connector> Instance(){
if(!instance)
{
instance = boost::shared_ptr<connector>(new connector());
}
return instance;
}
private:
connector(){}
static boost::shared_ptr<connector> instance;
};
#endif //TRANSMITTER_H
But get link error:
Error 3 error LNK2001: unresolved external symbol "private: static class boost::shared_ptr<class connector> connector::instance" (?instance#connector##0V?$shared_ptr#Vconnector###boost##A)
What is wrong with shared_ptr I want to return? Shall I make it function scope static variable?
This
static boost::shared_ptr<connector> instance;
inside your class definition is just a declaration. What you don't seem to have is a definition of it. This definition has be outside of the class definition.
However, you should probably prefer to do this:
class connector
{
public:
connector(connector const&) = delete;
connector& operator=(connector const&) = delete;
static boost::shared_ptr<connector> Instance()
{
static boost::shared_ptr<connector> instance (new connector);
return instance;
}
private:
connector(){}
};
In this case instance is defined as a static function-local object inside your inline function definition of Instance. The nice thing about it is that this kind of initialization is guaranteed to be thread-safe in C++11.
You should define
boost::shared_ptr<connector> connector::instance;
in your *.cpp
This makes linker allocate the memory for this static member in static data area.
You have to define static members outside of the class declaration. Here's what the definition looks like:
boost::shared_ptr<connector> connector::instance;
It should be in a cpp, for you probably transmitter.cpp

Accessing static variable from a friend function

class Base
{
private:
static int num;
public:
friend void setnum(Base obj);
};
void setnum(Base obj)
{
obj.num=4; /* Error */
}
A friend function is supposed to have access to all the private data of a class. what am i missing here? I cant seem to access the the static variable from the friend function.
Error from codepad--> In function
setnum(Base)': undefined reference to
Base::num'
Error from visual studio--> error LNK2001:
unresolved external symbol "private:
static int Base::num"
You only declared the static variable num. You must to define it:
class Base
{
private:
static int num;
public:
friend void setvals(Base obj);
};
// This must be in a .cpp
int Base::num;
void setvals(Base obj)
{
obj.num=4;
}
This code works.
Edit:
Actually you can implement the setvals() function as follows:
void setvals()
{
Base::num=4;
}
And at your Base class:
friend void setvals();
Because num is static.
Your free function is called setvals, but the Base's friend function is called setnum...
Besides you'll have to actually define the static variable, not just declare it.
Put:
int Base::num;
in a source file.
Different friends:
friend void setnum(Base obj);
// ^^^ Not the same as vals!
void setvals(Base obj)
In C++ it's not enough to declare a static variable in the .h; you must also define it explicitly in a .cpp. You must add in the .cpp of the implementation
int Base::num;
What you got was a linker error because of this missing variable definition.
Static variables don't belong to any particular instance of a class. Instead you may access them with a class name as Base::num to improve readability. Also, your friend function definition has a different signature than the one you declared.