singleton的实现与销毁(1) --modern c++读书笔记

## singleton的实现与销毁(1) –modern c++读书笔记##
1.Singleton的基本实现和注意点
Instance若是作为Singleton的静态成员对象。若是同样适用pInstance作为Singleton的静态成员指针。那么这两个版本有个重要差异:
Instance被动态初始化(通过执行期间的Singleton构造函数调用),pInstance则受益于静态初始化(其型别并无构造函数可通过编译器常量来初始化)。

上述结论的根据在于:程序的第一条assembly语句被执行之前,编译器就已经完成了静态初始化(通常静态初始化相关数值或动作(static initializers)就位于“内涵可执行程序”的文件中,所以,程序被装载(loading)之际也就是初始化之时)。

然而面对不同的编译单元即c++源码文件中的动态初始化对象,C++并未定义其间的初始化顺序!
错误例子请见:

//someFile.cpp
#include "Singleton.h"
int global=Singleton::Instance()->DoSomething();

由于无法保证编译器一定将instance初始化,所以全局变量global在进行定义且初始化时使用的Singleton::Instance()调用有可能传回的就是一个尚未构造的对象,因此显然无法保证外部访问的正确性。

2.实施“Singleton的唯一性”
(1)由于如果自己没有定义copy构造函数,编译器会帮你定义一个public版本。所以如果明确的自己定义了copy构造函数,就可以禁止编译器去自动生成。
而这里为了防止隐式的拷贝创建另外一个Singleton的对象,我们必须在private属性范围内定义一个copy构造函数,如果出现隐式的拷贝构造就会产生一个编译器错误,提醒我们代码有问题。
另外返回的指针改为引用更好,因为可以防止不小心调用delete将对象释放。
(2)编译器的另一个自动定义的是assignment操作符,由于唯一性导致Singleton对象不能赋予给另一个对象。所以应该的做法是将assignment操作符禁止,即将它声明为private并且根本不实现它将其实现为空。
(3) 为防止意外删除Singleton对象指针,将析构函数声明为private可以保证。

3.最重要的问题:如何销毁Singleton对象?
(1)为什么一定要销毁Singleton对象
首先明白内存泄露的定义:只有当你分配了累积性数据并丢失对它的所有reference时,内存泄露才会发生。
另外还有一点,当一个进程终止是,所有现代化操作系统都能够将进程所用的内存完全释放。
但是为什么还要销毁singleton对象,因为还存在资源泄露,比如网络连接,os中的mutexes,ipc的handlers等等,能够避免资源泄露的唯一方法就是在程序关闭时删除singletion对象。
(2)实现方法
<1>最简单的方法-依赖于语言机制
Instance适用一个局部静态变量;

Singletion& Singleton::Instance(){
    static Singleton obj;
    return obj;
}

区分“执行期才初始化”的static变量“通过编译期常量加以初始化”的基本型static变量


例如:

int Fun(){
    static int x=100;//“通过编译器常量加以初始化”
    return ++x;
}

这种情况下x的初始化会在程序中的任何一行被执行之前完成,而且通常是在程序装载期间。Fun()第一次被调用前,x早就被设成了100.
相比之下,若初始值不是一个编译期常量,抑或静态变量是个拥有构造函数的对象,那么变量的初始化将发生于执行期,也就是执行流程第一次执行到其定义语句的地方。
这里的100作为初始值显然是一个编译器常量,而这里实际上,编译器会产生一些代码,使得初始化之后,执行期香港机制会登记需要被析构的变量,其登记的核心函数就是atexit()。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值