0
votes

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();
};
2

2 Answers

3
votes

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() {}
};
0
votes

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”.