c++单例模式

class Singleton
{
    publicstatic Singleton* GetInstance();
        ~Singleton();
    private:
        static Singleton* p_singleton;
        Singleton();
}

实现

Singleton::Singleton() {
};
Singleton::~Singleton() {
}
Singleton* Singleton::GetInstance() {
    if(p_singleton == NULL) {
        p_singleton= new Singleton();
    }
}
Single::p_singleton =NULL;  //必要,类头文件中只是声明,并没有定义

当然,考虑到异常安全,可以加上锁。

Singleton::Singleton() {
};
Singleton::~Singleton() {
    if(p_singleton) {
      delete p_singleton;
     }
}
Singleton* Singleton::GetInstance() {
    Lock();
    if(p_singleton == NULL) {
        p_singleton= new Singleton();
    }
}
Single::p_singleton =NULL;  //必要,类头文件中只是声明,并没有定义

这样无论是不是第一个创建实例都要Lock,效率太低

Singleton::Singleton() {
};
Singleton::~Singleton() {
    if(p_singleton) {
      delete p_singleton;
     }
}
Singleton* Singleton::GetInstance() {
    if(p_singleton == NULL) {
        Lock();
        if(p_singleton == NULL) {
             p_singleton= new Singleton();
        }
    }
}
Single::p_singleton =NULL;  //必要,类头文件中只是声明,并没有定义

这样就好了。

但是这样存在另一个问题,这个实例如何delete;

可以在Singleton中自定义一个回收类,负责回收p_singleton

class Singleton
{
    publicstatic GetInstance();
        ~Singleton();
    private:
        class Garbo {
         public:
           ~Garbo() {
              if(p_singleton) {
                  delete p_singleton;
              }
           }
        }
        static Garbo garbo;
        static Singleton* p_singleton;
        Singleton();
}

程序结束会回收所有对象,包括gaobo,gaobo析构函数被调用,进而释放掉p_singleton;

单例模式还可以这么实现。

class Singleton {
public:
    static Singleton& GetInstance() ;
private:
    Singleton();
}
Singleton::Singleton() {
}
Singleton& GetInstance() {
   static Singleton MySingleton;
   return MySingleton;
}

当然,可以加锁。另外,编译器会自动添加copy构造函数和copy赋值函数,所以

Singleton singleton1= Singleton::GetInstance();

singleton不是GetInstance生成的sinleton,而是通过copy赋值函数构造出来的,这样就违反了单例的定义。

为了解决这个问题,可以声明Singleton的copy构造函数和copy赋值函数为私有变量,并且不去实现他们

class Singleton {
public:
    static Singleton& GetInstance() ;
private:
    Singleton(Singleton &rhs);
    Singleton& operator = (Singleton &rhs);
    Singleton();
}

这样就避免了赋值引起的问题