Static Template function access static class member - c++

I have a static template function inside a class that needs to access a static map inside the same class but I keep getting a unresolved external error when trying to access the map. Any Ideas?
Here's the code:
class Singleton
{
private:
static std::map<size_t, Singleton*> singletons;
public:
template<typename T>
static T* Get()
{
size_t type = typeid(T).hash_code();
if (singletons[type] == nullptr)
singletons[type] = new T();
return (T*)singletons[type];
}
};
Error Message:
error LNK2001: unresolved external symbol "private: static class std::map,class std::allocator > > Singleton::singletons" (?singletons#Singleton##0V?$map#IPAVSingleton##U?$less#I#std##V?$allocator#U?$pair#$$CBIPAVSingleton###std###3##std##A)

static class members need to be defined and declared in a compilation unit (in your case singletons member)
You need to add this line in a .cpp file:
std::map<size_t, Singleton*> Singleton::singletons;

Related

private: static class member initialization with inclass setter called by method in different class returns error - unresolved symbols [duplicate]

This question already has answers here:
Undefined reference to static class member
(9 answers)
Closed 7 months ago.
This post was edited and submitted for review 3 months ago and failed to reopen the post:
Original close reason(s) were not resolved
The question is a duplicate in concept, but the error is articulated differently. Unresolved symbols should be understood as undefined reference. If you are new to C++, please take the time to read the errors generated by my code.
I am taking a course in C++ and OOP, and I need some help understanding what I am doing wrong and what I can do to correct it.
I have a code skeleton, where I cannot change class members by changing them from static to non-static. In my current hand-out, I need to create an object of the first class in a second class, and call a method in the first class. I cannot move class members from private to public or public to private, and I cannot change them from static to non-static.
My goal is to write methods in the second class that uses the setters and getters from the first class, using an object in the second class, and to call the methods in the second class in int main().
Here is a basic idea of what I have written in attempting what I described.
#include <iostream>
using namespace std;
class foo
{
private:
static string goo;
static long int doo;
public:
static void setGoo(string gooString)
{
goo = gooString;
}
static void setDoo(long int dooLongInt)
{
doo = dooLongInt;
}
static string getGoo()
{
return goo;
}
static long int getDoo()
{
return doo;
}
};
class moo
{
private:
foo fooObj;
public:
void setGoo(string gooString)
{
fooObj.setGoo(gooString);
}
void setDoo(long int dooLongInt)
{
fooObj.setDoo(dooLongInt);
}
string getGoo()
{
return fooObj.getGoo();
}
long int getDoo()
{
return fooObj.getDoo();
}
};
int main()
{
moo mainMoo;
string text = "Text";
mainMoo.setGoo(text);
mainMoo.setDoo(123);
cout << mainMoo.getGoo();
cout << mainMoo.getDoo();
return 0;
};
I get these errors when I compile it.
1>Source.obj : error LNK2001: unresolved external symbol "private: static class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > foo::goo" (?goo#foo##0V?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##A)
1>Source.obj : error LNK2001: unresolved external symbol "private: static long foo::doo" (?doo#foo##0JA)
1>C:\Users\ipyra\OneDrive\Documents\edx hands-on projects\Static class private member initialization\x64\Debug\Static class private member initialization.exe : fatal error LNK1120: 2 unresolved externals
Class static members need to initialize outside a class, that is the reason of link error.
class foo
{
private:
static string goo;
static long int doo;
public:
// .... other code
};
string foo::goo = "";
long int foo::doo = 0;
Use inline keyword in C++ 17, we can defined static member inside class.
http://en.cppreference.com/w/cpp/language/static
Another similar question
How to initialize private static members in C++?

How to typedef a class constructor inside the class definition

The title might be unclear but the code is simple and should explain itself. I would like to typedef a constructor to my class inside the class and then set the address of said constructor elsewhere.
class Dog {
public:
typedef Dog* (__thiscall* Constructor_T)(Dog* thisptr);
static Constructor_T Constructor;
Dog() {
Constructor(this);
}
};
void SetDogConstructor() {
Dog::Constructor = (Dog::Constructor_T)0x1234;
}
The error I receive is:
Error 2 error LNK2001: unresolved external symbol "public: static class Dog * (__thiscall* Dog::Constructor)(class Dog *)" (?Constructor#Dog##2P6EPAV1#PAV1##ZA)
A static member needs a definition outside the class. In your case, you would put
Dog::Constructor_T Dog::Constructor = nullptr;
in Dog.cpp.

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

Singleton Inheritance Linker Error

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.