C++回顾之static与单例模式

        单例模式是应用最多的一种设计模式,它要求每个类有且只能有一个实例对象,所以用C++设计一个单例模式的方法如下:

        1 构造函数声明为私有;   这样就保证了不能随意构造一个对象

        2 将拷贝构造函数与等号运算符声明为私有,并不提供他们的实现; 即禁止对象被拷贝。

        3 在类中声明一个静态的全局访问接口;

        4 声明一个静态的私有实例化指针;

        

class Singleton
{
public:
    //全局访问接口
    static Singleton *GetInstance()
    {
        if( instance_ == NULL )
        {
            instance_ = new Singleton;
        }
        return instance_;
    }

    ~Singleton()
    {
        cout << "~Singleton"<< endl;
    }

private:
    Singleton(const Singleton& other);
    Singleton & operator=(const Singleton & other);
    Singleton()
    {
          cout << "Singleton"<<endl;
    }


    static Singleton *instance_; //引用性声明
};

Singleton * Singleton::instance_; //定义性声明

int main(void)
{
    Singleton *s1 = Singleton::GetInstance();
    Singleton *s2 = Singleton::GetInstance();  //s2的地址等于s1,即指向同一对象

    //Singleton s3(*s1); //既然是单例模式,是不允许被拷贝的。编译会出错

    return 0;
}

        上面就是单例类模式的C++实现,但是上述代码还有一个缺陷: 单例类中申请的一些资源没有被释放,如instance_指向的空间没有被回收。一共有两种解决方式:

        第一种解决方式:

        

class Singleton
{
    ...
    //提供一个回收接口,在应用中显示调用回收资源
    static void Free()
    {
        delete instance_;
    }

    ....
};

int main()
{
    ...
    Singleton::Free(); //要显示调用进行资源回收
}
        这种方式虽然能实现功能,但是不太方便,每次都要手动回收资源,这是它的缺点。

        第二种解决方式:

class Singleton
{
    ...
public:
    class Garbo //资源回收机制
    {
    public:
        ~Garbo()
        {
            if( Singleton::instance_ != NULL )
            {
                delete instance_;
            }
        }
    };

    ...
private:
    ...
    static Garbo garbo_;  //引用性声明
};

Singleton::Garbo Singleton::garbo_;//定义性声明
        这种方式提供的处理方式显然要比第一种方式来的要便捷,因为它依靠内部提供的Garbo嵌套类来提供服务,当Singleton类生命周期结束时,Garbo的类对象garbo_也要销毁,它将调用析构函数,而在析构函数中又自动地释放了Singleton单例类申请的一些资源,这种实现就比较智能化。不需要手动释放资源。这是它的优势。

        

        下面提供另一种实现C++单例类模式的方法:

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

    ~Singleton()
    {
        cout << "~Singleton"<<endl;
    }
private:

    Singleton()
    {
        cout << "Singleton "<<endl;
    }
    Singleton(const Singleton &other);
    Singleton & operator=(const Singleton &other);
};
        这种实现方式利用了static修改函数内部的变量,当第一次调用GetInstance函数时,系统将构造一个Singleton对象,在后续再次调用这个函数时,系统不再执行这个语句,也就不会再构造Singleton类对象了,而直接返回instance_本身。另外,当Singleton类对象生命周期结束时,对象会自动调用析构函数销毁,这里也就不存在申请资源之类的了,需要注意的是GetInstance()函数返回的是引用,这样就不会调用拷贝构造函数了,使用时也应该声明Singleton的引用,如下:

       

int main()
{
    Singleton &s1 = Singleton::GetInstance();
    Singleton &s2 = Singleton::GetInstance(); //s1与s2是同一对象的引用

    return 0;
}

  • 7
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值