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
Related
This question already has answers here:
Undefined reference to a static member of the class
(2 answers)
Closed 8 years ago.
The following code is generating a linker error while compiling with Visual Studio 2013.
#define MAX_CONTROLLERS 4
class JoypadController {
public:
JoypadController() : m_is_connected(false), m_gamepad(0), m_instance_id(-1), m_haptic(0) {}
int JoypadController::processEvent(const SDL_Event& event);
private:
SDL_GameController *m_gamepad;
SDL_Haptic *m_haptic;
SDL_JoystickID m_instance_id;
bool m_is_connected;
static JoypadController m_controllers[MAX_CONTROLLERS];
static int GetControllerIndex(SDL_JoystickID instance);
void Open(int device);
void Close();
};
static JoypadController m_controllers[MAX_CONTROLLERS];
1>joypad.obj : error LNK2001: unresolved external symbol "private: static class JoypadController * JoypadController::m_controllers" (?m_controllers#JoypadController##0PAV1#A)
Is this valid for the class JoypadController to use itself as a type? Am I missing something simple in my linker?
Yes, a class can contain a static member of the same type as the class. Example:
struct S {
static S s; // declaration
};
S S::s {}; // definition
int main() {}
A member shall not be defined to have an incomplete type, and within the definition of a class, that class itself is incomplete. This is why you can't have a non-static member of the same type as the class itself. However, declaring a static member of a class does not define that static member. Declare it within the class definition, then define it further down.
If you use the static member without defining it, you will get a link error. This has nothing to do with the fact that the static member has the same type as the class. Whenever you try to use an object that hasn't been defined, you will get a link error.
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”.
I want to write a little Singleton class that looks like:
#include <vector>
class Interpreter {
private:
static Interpreter* interInstance;
Interpreter() {}
public:
static Interpreter* getInstance();
~Interpreter() {}
};
Interpreter* Interpreter::interInstance = 0;
Interpreter* Interpreter::getInstance(){
if (!interInstance)
interInstance = new Interpreter();
return interInstance;
}
But this will produce this exception:
multiple definition of `Interpreter::getInstance()
This error can be corrected by wrapping the class and the function in one namespace.
But I don't really understand why I need a namespace.
There is one declaration of getInstance() and one implementation, no?
Move the definition outside the header, in an implementation file, for both the member initialization and the method:
Interpreter.h
class Interpreter {
private:
static Interpreter* interInstance;
Interpreter() {}
public:
static Interpreter* getInstance();
~Interpreter() {}
};
Interpreter.cpp
#include "Interpreter.h"
Interpreter* Interpreter::interInstance = 0;
Interpreter* Interpreter::getInstance(){
if (!interInstance)
interInstance = new Interpreter();
return interInstance;
}
Inside a class or struct definition, static doesn't give symbols internal linkage as it does outside, so you're breaking the one definition rule.
If multiple translation units include a header that contains non-inline methods or define the same symbol, you'll run into multiple definition.
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.
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.