单例销毁_小小白带你实现C++单例模式

f97b2932f867e1ad4412965b66490d81.png

单例模式是一种较为简单的设计模式,可根据不同需求有不同的实现方法。但是单例模式是有局限性的,索引很多人会反对使用单例模式,本文一步一步循序渐进地实现简单的单例模式。

什么是单例模式

单例 Singleton 是设计模式的一种,要求内存中只能创建一个对象,具有全局变量的特点,在任何位置都可以通过接口获取到那个唯一实例;

应用场景:

1. 直接替换任意的全局对象(变量)
2. 配置文件
3. 词典类
4. 设备管理器,系统中可能有多个设备,但是只有一个设备管理器,用于管理设备驱动
5. 数据池,用来缓存数据的数据结构,需要在一处写,多处读取或者多处写,多处读取

C++单例模式的实现

首先来看这段代码

#include <iostream>
#include <stdio.h>
using std::cout;
using std::endl;

//创建一个类
class Singleton {

};
int main() {
    Singleton s1;
    Singleton s2;  //可以创建多个对象
    return 0;
}

按照普通的方式创建一个类,这样就可以创建多个对象,所以让main中的Singleton s1;编译不通过。因为创建实例的时候会调用构造函数,所以我们可以从构造函数下手,将构造函数放在设为私有

private:
    Singleton() {
        cout << "构造函数: Singleton()  "<< endl;
    }

将构造函数私有化后下面的几种创建实例方式都会报错

Singleton s3;   //error
static Singleton s4;  //error

int main() {
    //设为私有后,下面的语句将会报错
    Singleton s1;
    Singleton s2;  //可以创建多个对象

    Singleton * p1 = new Singleton();  //error
    return 0;
}

private中的成员方法只能在类本身中调用,所以在中定义getInstance()方法,返回的是一个Singleton对象。

class Singleton {
public:
    static Singleton * getInstance() {
        return new Singleton();
    }
private:
    Singleton() {
        cout << "构造函数: Singleton()  "<< endl;
    }
};
int main() {

    Singleton *p1 = Singleton::getInstance();
    Singleton *p2 = Singleton::getInstance();
    //打印地址
    printf("&P1 = %pn",p1);
    printf("&P1 = %pn",p2);
    return 0;
}

用静态成员函数创建对象,通过打印地址发现,这两个对象地址不一样,说明不是同一对象, 所以需要用一个变量保存第一次创建之后的指针。但是这个变量_pInstance必须是static的,因为是在静态方法中使用。此外静态成员必须在类的外部进行初始化。
这时打印p1p2的地址,发现地址是一样的, 说明是同一个对象。

class Singleton {
public:
    static Singleton * getInstance() {
        if (NULL == _pInstance) {
            _pInstance = new Singleton();
        }
        return _pInstance;
    }
private:
    Singleton() {
        cout << "构造函数: Singleton()  "<< endl;
    }
private:
    static Singleton * _pInstance;
};

//静态成员必须初始化
Singleton * Singleton::_pInstance = NULL;

int main() {
    Singleton *p1 = Singleton::getInstance();
    Singleton *p2 = Singleton::getInstance();
    //打印地址
    printf("&P1 = %pn",p1);
    printf("&P1 = %pn",p2);  //地址一样
    return 0;
}

对象的销毁 我们可以直接通过delete p1;去销毁,但是我们是通过静态方法创建的对象,最后也是用静态的方法销毁,所以必须让这条语句编译不通过。由于对象在销毁的时候会调用析构函数,所以,我们可以把析构函数设置成私有的。然后在类内部定义一个destory()函数。

class Singleton {
public:
    static Singleton * getInstance() {
        if (NULL == _pInstance) {
            _pInstance = new Singleton();
        }
        return _pInstance;
    }
    //销毁函数
    static void destory() {
        if (_pInstance) {
            delete _pInstance;  //_pInstance存的就是对象
        }
    }
private:
    Singleton() {
        cout << "构造函数: Singleton()  "<< endl;
    }
    ~Singleton() {
        cout << "析构函数:~Singleton()" << endl;
    }
private:
    static Singleton * _pInstance;
};

//静态成员必须初始化
Singleton * Singleton::_pInstance = NULL;

int main() {
    Singleton *p1 = Singleton::getInstance();
    Singleton *p2 = Singleton::getInstance();
    //打印地址
    printf("&P1 = %pn",p1);
    printf("&P1 = %pn",p2);  //地址一样

    //    delete p1;  //希望该语句编译无法通过(析构函数就必须放在private区域)

    Singleton::destory();
    return 0;
}

最终运行结果:

构造函数: Singleton()  
&P1 = 0x7fa0c54006a0
&P1 = 0x7fa0c54006a0
析构函数:~Singleton()
这次先讲这么多啦,下次再继续深入~
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值