0

I was trying to implement singleton pattern with an assumption of just using a private constructor, private instance of the class and a public static method to return the instance. But I encountered an error to the following code in Visual Studio

// Singleton Invoice
#include <iostream>
using namespace std;

class Singleton {
public:
  //Public Static method with return type of Class to access that instance.
  static Singleton* getInstance();
private:
  //Private Constructor
  Singleton();
  //Private Static Instance of Class
  static Singleton* objSingleton;
};

Singleton* Singleton::objSingleton = NULL;

Singleton* Singleton::getInstance() {
  if (objSingleton == NULL) {
    //Lazy Instantiation: if the instance is not needed it will never be created
    objSingleton = new Singleton();
    cout << "Object is created" << endl;
  }
  else
  {
    cout << "Object is already created" << endl;
  }
  return objSingleton;
}

int main() {
  Singleton::getInstance();
  Singleton::getInstance();
  Singleton::getInstance();
  return 0;
}

The error as :

LNK2019 unresolved external symbol "private: __thiscall Singleton::Singleton(void)" (??0Singleton@@AAE@XZ) referenced in function "public: static class Singleton * __cdecl Singleton::getInstance(void)" (?getInstance@Singleton@@SAPAV1@XZ)

Then I resolved the error but rewriting the constructor outside the class

Singleton::Singleton() {
}

I would like to know the cause for the error and why a constructor needs to be explicitly written outside the class.

CantrianBear
  • 1,013
  • 1
  • 12
  • 22
xAditya3393
  • 149
  • 4
  • 12
  • I think its because you declared the constuctor but didn't implement it. BTW are you a Fanshawe College student by chance? Just curious – kburlz Apr 22 '16 at 04:04
  • You're creating pointers to your getInstance method and singleton object. Have you tried dereferencing in main? – almostcolin Apr 22 '16 at 04:04
  • 1
    @kburlz I am a student at University of Bridgeport :D , This was an example my professor found on internet to teach us Singleton pattern so when I was writing it on my own, I encountered the problem and was curious about it. I guess you might have been taught through the same example :D – xAditya3393 Apr 22 '16 at 07:05
  • @almostcolin When I first saw the error I got was thinking maybe the compiler wasn't able to distinguish static object and the get method, so when I looked back to the lecture slides, I noticed the constructor being explicitly specified – xAditya3393 Apr 22 '16 at 07:15
  • Possible duplicate of [C++ Singleton design pattern](https://stackoverflow.com/questions/1008019/c-singleton-design-pattern) – Trevor Boyd Smith Sep 04 '18 at 12:11

5 Answers5

3

The default constructor needs a body:

You could change

Singleton();

to

Singleton(){};

inside the class and it should work.

jbrove
  • 121
  • 3
3

In the class the constructor was only declared, not defined. A definition includes a function body. It doesn't matter much whether you define it inline in the class, or outside the class (as you did), but one little difference is that with a definition in the class it's implicitly inline.


In other news:

  • Singletons improve on global variables by avoiding e.g. the static initialization order fiasco, but have the same problems with respect to invisible lines of communication and side effects. Best avoided.

  • If you don't need a singleton to persist after a corresponding global variable would be destroyed, then just use a simple Meyers' singleton.

Here's a Meyers' singleton:

class Foo
{
private:
    Foo() {}
public:
    static auto instance()
        -> Foo&
    {
        static Foo the_instance;
        return the_instance;
    }
};
Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • So, am I right in assuming the static variable Foo being created only when the function is called? Unlike the normal singleton where static variable is being created and inefficiency being introduced when the variable is never used? – xAditya3393 Apr 22 '16 at 07:34
  • @PagadalaVikramaditya: Yes, that's right. It's created the first time execution passes through the declaration, which is the first time `instance` is called. And in C++11 and later this is even thread-safe. – Cheers and hth. - Alf Apr 22 '16 at 08:47
1

With C++11 we can use the 'default' specifier to instruct the compiler to create the default implementation of the constructor.

Refer to the below code snippet which is working for me:

class Singleton
{
    static Singleton* m_instance;
    Singleton()=default;   /* Note the use of default specifier here*/
public:
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;
    static Singleton* getInstance()
    {
        if(!m_instance){m_instance= new Singleton();}
        return m_instance;
    }
};
Akash
  • 36
  • 5
0

In an evolution of the Meyer's singleton, I prefer the value-semantic singleton, for reasons mentioned in the code below:

class singleton
{
  // private implementation
  struct impl {
    void do_something() { }
  };

  // private decision as to whether it's really a singleton and what its lifetime
  // will be
  static impl& instance() { static impl _impl; return _impl; }

public:
  // public interface defers to private lifetime policy and implementation
  void do_something() { instance().do_something(); }
};

void something(singleton s)
{
  s.do_something();
}

int main()
{
  // we can now pass singletons by value which gives many benefits:
  // 1) if they later become non-singletons, the code does not have to change
  // 2) the implementation can be private so better encapsulation
  // 3) we can use them in ADL more effectively
  auto x = singleton();
  something(x);
  something(singleton());
}
Richard Hodges
  • 68,278
  • 7
  • 90
  • 142
0

Pagadala is right. The constructor definition is missing hence the linker error