Explicitly stating a Constructor outside the class

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.


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 eg 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;
        }
    };
    

    The default constructor needs a body:

    You could change

    Singleton();
    

    to

    Singleton(){};
    

    inside the class and it should work.


    在迈尔单身人士的演变中,我更喜欢价值语义单身人士,原因如下:

    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());
    }
    
    链接地址: http://www.djcxy.com/p/78848.html

    上一篇: 使用GCD的调度创建单例

    下一篇: 在类之外明确声明构造函数