C++ Singleton undefined reference to - c++

I am new to C++ and trying to understand the Singleton Pattern in C++.
myclass.h
#ifndef MYCLASS_H
#define MYCLASS_H
class Myclass {
public:
static Myclass* getInstance();
private:
Myclass(){}
Myclass(Myclass const&){}
Myclass& operator=(Myclass const&){}
static Myclass* m_instance;
};
#endif // MYCLASS_H
myclass.cpp
#include "myclass.h"
Myclass* Myclass::getInstance() {
if (!m_instance) {
m_instance = new Myclass;
}
return m_instance;
}
The compiler can't compile. I get the following error, on all 3 lines with m_instance:
error: undefined reference to `Myclass::m_instance'

You forgot to add:
Myclass* Myclass::m_instance = 0; // or NULL, or nullptr in c++11
right under #include "myclass.h".

Related

How to make a class static variable which depends on the complete class type a constexpr?

I have a class MyClass which has a static variable instance. The value of instance is a compile-time constant, but it depends on the complete type MyClass. Is there any way to make instance a constexpr?
// memchunk.hpp
#ifndef MEMCHUNK_HPP
#define MEMCHUNK_HPP
#include <new>
#include <utility>
enum class DestroyOption {
Implicit,
Explicit,
};
// a wrapper for placement new
template <class T, DestroyOption Opt = DestroyOption::Implicit> class MemChunk {
alignas(T) char buf[sizeof(T)];
public:
template <typename... Args> void construct(Args &&...args) {
new (buf) T(std::forward<Args>(args)...);
}
void destroy() { get()->~T(); }
constexpr T *get() { return reinterpret_cast<T *>(buf); }
~MemChunk() {
if constexpr (Opt == DestroyOption::Implicit)
destroy();
}
};
#endif // MEMCHUNK_HPP
// myclass.cpp
#include "memchunk.hpp"
// struct MyClass; // forward declaration
// MemChunk<MyClass> obj; // error: incomplete type MyClass
class MyClass {
static const MyClass *instance; // better to be constexpr
};
MemChunk<MyClass> obj;
const MyClass *MyClass::instance = obj.get();
Use a function instead:
class MyClass {
static constexpr MyClass* instance();
};
MemChunk<MyClass> obj;
constexpr MyClass* MyClass::instance() {
return obj.get();
}
However, this is pointless because obj.get() cannot be used in a constexpr context (because of the reinterpret_cast, as mentioned in the comments).
Demo

C++ Link Error when I was implementing template Singleton class

I'm implementing a Singleton template in C++. I try to achieve thread-safe by std::call_once and std::once_flag, but somehow link error happens.
singleton.h
#ifndef _SINGLETON_H_
#define _SINGLETON_H_
#include <boost/noncopyable.hpp>
#include <mutex>
template<typename T>
class Singleton : boost::noncopyable {
public:
Singleton() = delete;
static T& getInstance() {
std::call_once(init_flag_, &Singleton::init);
return *val_;
}
private:
static void init() {
val_ = new T();
}
private:
static std::once_flag init_flag_;
static T* val_;
};
#endif // _SINGLETON_H_
test_singleton.cc
#include "singleton.h"
#include <iostream>
class Log {
public:
void log() {
std::cout << "log" << std::endl;
}
};
int main() {
Log & logger = Singleton<Log>::getInstance();
logger.log();
}
And my g++ statement is
g++ -std=c++14 -pthread -o test test_singleton.cc
Error message:
/tmp/ccoxQBXl.o: In function `Singleton<Log>::getInstance()':
test_singleton.cc:(.text._ZN9SingletonI3LogE11getInstanceEv[_ZN9SingletonI3LogE11getInstanceEv]+0x2c): undefined reference to `Singleton<Log>::init_flag_'
test_singleton.cc:(.text._ZN9SingletonI3LogE11getInstanceEv[_ZN9SingletonI3LogE11getInstanceEv]+0x38): undefined reference to `Singleton<Log>::val_'
/tmp/ccoxQBXl.o: In function `Singleton<Log>::init()':
test_singleton.cc:(.text._ZN9SingletonI3LogE4initEv[_ZN9SingletonI3LogE4initEv]+0x11): undefined reference to `Singleton<Log>::val_'
collect2: error: ld returned 1 exit status
Finally got it. The only problem is I didn't initialize the static variables.
For C++17, inline keyword allows initialization within class.
#ifndef SINGLETON_H_
#define SINGLETON_H_
#include <boost/noncopyable.hpp>
#include <mutex>
template<typename T>
class Singleton : boost::noncopyable {
public:
Singleton() = delete;
static T& getInstance() {
std::call_once(init_flag_, &Singleton::init);
return *val_;
}
private:
static void init() {
val_ = new T();
}
private:
static inline std::once_flag init_flag_{};
static inline T* val_ = nullptr;
};
#endif // SINGLETON_H_

Qt Singleton implementation

I was looking for a Singleton Qt implementation and found this. but I have some question about it.
What is the purpose of making create a QBasicAtomicPointer ?
What is the point in qCallOnce of using testAndSetRelaxed if previously we have used fetchAndStoreAcquire ? Isn't the acquire semantic already preventing any memory reordering after it ?
What is the purpose of the qCallOncePerThread function ? Isn't qCallOnce already thread-safe ?
I copy the contents of the suggested implementation here:
call_once.h
#ifndef CALL_ONCE_H
#define CALL_ONCE_H
#include <QtGlobal>
#include <QAtomicInt>
#include <QMutex>
#include <QWaitCondition>
#include <QThreadStorage>
#include <QThread>
namespace CallOnce {
enum ECallOnce {
CO_Request,
CO_InProgress,
CO_Finished
};
Q_GLOBAL_STATIC(QThreadStorage<QAtomicInt*>, once_flag)
}
template <class Function>
inline static void qCallOnce(Function func, QBasicAtomicInt& flag)
{
using namespace CallOnce;
#if QT_VERSION < 0x050000
int protectFlag = flag.fetchAndStoreAcquire(flag);
#elif QT_VERSION >= 0x050000
int protectFlag = flag.fetchAndStoreAcquire(flag.load());
#endif
if (protectFlag == CO_Finished)
return;
if (protectFlag == CO_Request && flag.testAndSetRelaxed(protectFlag,
CO_InProgress)) {
func();
flag.fetchAndStoreRelease(CO_Finished);
}
else {
do {
QThread::yieldCurrentThread();
}
while (!flag.testAndSetAcquire(CO_Finished, CO_Finished));
}
}
template <class Function>
inline static void qCallOncePerThread(Function func)
{
using namespace CallOnce;
if (!once_flag()->hasLocalData()) {
once_flag()->setLocalData(new QAtomicInt(CO_Request));
qCallOnce(func, *once_flag()->localData());
}
}
#endif // CALL_ONCE_H
singleton.h
#ifndef SINGLETON_H
#define SINGLETON_H
#include <QtGlobal>
#include <QScopedPointer>
#include "call_once.h"
template <class T>
class Singleton
{
private:
typedef T* (*CreateInstanceFunction)();
public:
static T* instance(CreateInstanceFunction create);
private:
static void init();
Singleton();
~Singleton();
Q_DISABLE_COPY(Singleton)
static QBasicAtomicPointer<void> create;
static QBasicAtomicInt flag;
static QBasicAtomicPointer<void> tptr;
bool inited;
};
template <class T>
T* Singleton<T>::instance(CreateInstanceFunction create)
{
Singleton::create.store(create);
qCallOnce(init, flag);
return (T*)tptr.load();
}
template <class T>
void Singleton<T>::init()
{
static Singleton singleton;
if (singleton.inited) {
CreateInstanceFunction createFunction = (CreateInstanceFunction)Singleton::create.load();
tptr.store(createFunction());
}
}
template <class T>
Singleton<T>::Singleton() {
inited = true;
};
template <class T>
Singleton<T>::~Singleton() {
T* createdTptr = (T*)tptr.fetchAndStoreOrdered(nullptr);
if (createdTptr) {
delete createdTptr;
}
create.store(nullptr);
}
template<class T> QBasicAtomicPointer<void> Singleton<T>::create = Q_BASIC_ATOMIC_INITIALIZER(nullptr);
template<class T> QBasicAtomicInt Singleton<T>::flag = Q_BASIC_ATOMIC_INITIALIZER(CallOnce::CO_Request);
template<class T> QBasicAtomicPointer<void> Singleton<T>::tptr = Q_BASIC_ATOMIC_INITIALIZER(nullptr);
#endif // SINGLETON_H
How to use
// myclass.h
#ifndef MYCLASS_H
#define MYCLASS_H
#include <QObject>
class MyClass : public QObject
{
Q_OBJECT
private:
MyClass(QObject* parent = 0);
static MyClass* createInstance();
public:
~MyClass();
static MyClass* instance();
};
#endif // MYCLASS_H
// myclass.cpp
#ifndef MYCLASS_H
#define MYCLASS_H
#include <QObject>
#include "singleton.h"
MyClass::MyClass(QObject* parent):
QObject(parent)
{
}
MyClass* MyClass::createInstance()
{
return new MyClass();
}
MyClass::~MyClass()
{
}
MyClass* MyClass::instance()
{
return Singleton<MyClass>::instance(MyClass::createInstance);
}
#endif // MYCLASS_H
main.cpp
#include <QTextStream>
#include "myclass.h"
#define MyClassInstance Singleton<MyClass>::instance()
int main(int argc, char* argv[])
{
QTextStream(stdout) << MyClass::instance()->metaObject()->className() << endl;
return 0;
}
I think that is will be enough to use next singleton implementation. As I remember, C++11 gurantees that there will be only one instancing/initialization for a static variable.
Original problem was in case, when more than one thread tries to access an instance in same time and there were possible a situation, when singleton was created twice.
template <typename T, typename D = T>
class Singleton
{
friend D;
static_assert(std::is_base_of_v<T, D>, "T should be a base type for D");
public:
static T& instance();
private:
Singleton() = default;
~Singleton() = default;
Singleton( const Singleton& ) = delete;
Singleton& operator=( const Singleton& ) = delete;
};
template <typename T, typename D>
T& Singleton<T, D>::instance()
{
static D inst;
return inst;
}
// Usage:
class MyClass : public Singleton<MyClass>
{
public:
void foo(){}
};
// Access:
MyClass::instance().foo();
Main concept of using Singleton pattern is to restrict the instantiation to certain number of objects, in common use to one.
Q1 : Atomic pointer
Atomic operations are done without interruption , so handled multi-thread instance calls.
Q2 : point of qCallOnce
This function checks if any other threads are executing and if so wait for CO_finished flag in
do {
QThread::yieldCurrentThread();
}
while (!flag.testAndSetAcquire(CO_Finished, CO_Finished));
Q3 : point of qCallOncePerThread
if (!once_flag()->hasLocalData()) {
once_flag()->setLocalData(new QAtomicInt(CO_Request));
I think to handle LocalData of singleton class per each thread instacnes

What is the right way of setting member pointers to null in a singleton class

In myClass, I have a pointer of type helper, and I would like to set it to null.
Can I initialize it to null in the getInstance() function, or can I set it to null pointer in the declaration itself?
What's the best way to set it to null?
class myClass
{
public:
static myClass* getInstance();
static void destroy();
Helper* Helper_;
private:
static myClass* instancePtr_;
// Private so that object can not be created outside
myClass(){};
~myClass(){};
myClass(const myClass&);
myClass& operator =(const myClass&);
}
myClass* myClass::instancePtr_ = NULL;
myClass* myClass::getInstance()
{
if (!instancePtr_)
{
instancePtr_ = new myClass;
}
return instancePtr_;
}
In myClass i have a pointer of type helper and i would like to set it to null.
You can initialize it in the declaration:
Helper* Helper_ = nullptr;
In pre-C++11 mode, initialize it in the constructor:
myClass() : Helper_(NULL) {};
You can also omit NULL initializer, turning it into value-initialization, with the same effect:
myClass() : Helper_() {};
The idiom used in frameworks where the static initialization order fiasco would make life hard is to let the user construct the object explicitly within e.g. main(), and enforce the single instance if the class needs to be truly a singleton or if it's used as if it was a singleton. The constructor then should use the initializer list (the below is C++03):
// interface
class MyClassBase {};
class MyClass : private MyClassBase {
MyClass(const MyClass &); /* = delete */
MyClass & operator=(const MyClass &); /* = delete */
static MyClassBase * m_instance;
Helper * m_helper;
public:
MyClass();
~MyClass();
static MyClass * instance(); // only usable if there's no more than one instance
};
// implementation
static MyClassBase null;
MyClassBase * MyClass::m_instance;
MyClass::MyClass() : m_helper{0} {
// optional if there truly can only be one instance
assert(!m_instance);
// invalidate the global pointer if we're not a singleton anymore
if (!m_instance)
m_instance = this;
else
m_instance = &null;
}
MyClass * MyClass::instance() {
assert(m_instance != &m_null);
return static_cast<MyClass*>(m_instance);
}
MyClass::~MyClass() {
if (m_instance != &null)
m_instance = 0;
}
// use
int main() {
MyClass my;
...
}
In C++11, you'd instead write:
class MyClassBase {};
class MyClass : private MyClassBase {
MyClass(const MyClass &) = delete;
MyClass & operator=(const MyClass &) = delete;
static MyClassBase * m_instance;
Helper * m_helper = {};
public:
MyClass();
~MyClass();
static MyClass * instance();
};
MyClass::MyClass() { ... }
MyClass::~MyClass() {
if (m_instance != &null)
m_instance = nullptr;
}

How to use forward class declaration in a function with template?

I have two classes. Each has a pointer pointing to the other class. So I have to use forward class declaration in one of them. This method runs well until I need to use a function with template (which I have to write both the declaration and implementation in the header file).
More specifically, my codes are something like the following files. These files got compiled without problems on Windows by MS Visual Studio 2010. But when I compile them on Mac by XCode 4.3.2, I got an error of "Member access into incomplete type 'ClassB'" in file ClassA.h.
Can anyone tell me how to make it compilable on Mac with XCode?
file ClassA.h
#ifndef CLASS_A
#define CLASS_A
//#include "ClassB.h"
class ClassB;
class ClassA
{
public:
ClassA();
template <typename T>
void funcA(T *t);
int iNum;
ClassB *pB;
};
template <typename T>
void ClassA::funcA(T *t)
{
iNum = *(int*)t;
iNum += pB->iNum;
}
#endif
file ClassA.cpp
#include "ClassA.h"
ClassA::ClassA()
{
iNum = 1;
}
file ClassB.h
#ifndef CLASS_B
#define CLASS_B
#include "ClassA.h"
class ClassB
{
public:
ClassB();
template <typename T>
void funcB(T *t);
int iNum;
ClassA *pA;
};
template <typename T>
void ClassB::funcB(T *t)
{
iNum = *(int*)t;
iNum -= pA->iNum;
}
#endif
file ClassB.cpp
#include "ClassB.h"
ClassB::ClassB()
{
iNum = 2;
}
Main file
#include <stdio.h>
#include "ClassA.h"
#include "ClassB.h"
int main(void)
{
ClassA objA;
ClassB objB;
objA.pB = &objB;
objB.pA = &objA;
int a = 11;
int b = 22;
objA.funcA(&a);
objB.funcB(&b);
printf("Class A: %d, %d\n", objA.iNum, objA.pB->iNum);
printf("Class B: %d, %d\n", objB.iNum, objB.pA->iNum);
return 0;
}
You access pB->iNum in your function definition, which is not known from A class since you did not include classB.h.
Foward declaration helps you to define classes, you can then include your header files. Try something like this:
#ifndef CLASS_A
#define CLASS_A
class ClassB;
class ClassA
{
public:
ClassA();
template <typename T>
void funcA(T *t);
int iNum;
ClassB *pB;
};
#include "ClassB.h"
template <typename T>
void ClassA::funcA(T *t)
{
iNum = *(int*)t;
iNum += pB->iNum;
}
#endif
And do the same in classB.h