脚跟脚设计单件模式—第二脚

将Parameters设计成单件模式

保障 Parameters 只能有一个孩子的做法就是将默认构造函数和拷贝构造函数设计成私有变量,把他们保护起来,这样客户程序就不能通过 Parameters para; Parameters* para = new Parameters(); 这样的操作创建Parameters 对象了, 客户程序得到Parameters对象的途径只有一个,就是调用 Parameters* para = Parameters::Instance();如果客户程序强制使用Parameters para; Parameters* para = new Parameters();创建新的类对象,在编译的时候就会出错,这个正式单件模式的所要达到的效果。

 

单件对象的使用时创建
有人可能会提出,就上面单件模式实现中的 static Parameters* instance; 用 static Parameters instance;替换可以达到同样的效果,如下代码所示:

 
上面的实现时不可取的,主要有两个原因
1. 第一个实现中instance指针所指向的Parameters对象是在第一次调用 Parameters::Instance()的时候创建的,这样就实现了使用时创建对象。延迟指针绑定为程序提供了只在必要的时候创建类对象这个特征,节省了系统的资源;
2. 第二个实现中,在有的编译器生成的程序运行时,可能产出“对象未构造”的错误。instance的实体对象和指针对象的构造过程是不同的,static Parameters* instance;是静态初始化(编译的时候初始化,并不调用Parameters的构造函数),而static Parameters instance;是动态初始化(执行期间调用Parameters的构造函数),动态初始化时,C++并不保障不同编译单元中的 static 对象的初始化顺序,这样在客户程序执行  Parameters::Instance().AddParameter(para); 的时候,可能 instance 并没有被构造好。

 

改进Parameters单件实现
编译器的自动化有时候会帮你的倒忙,在单件模式的实现中是这样的。如果在你的类设计中没有显示的实现默认构造函数、拷贝构造函数、赋值操作符,编译器会自动为你生成。如果客户程序这样使用Parameters类对象:Parameters paras (*Parameters::Instance());,就会破坏单件对象的唯一性,这也是上面的实现中屏蔽拷贝构造的原因。
 
第一个改进:屏蔽赋值操作符
赋值和唯一性没有直接的关系,任何Parameters对象的赋值操作都是对自身的赋值,但是这没有任何意义。做法就是将赋值操作放到privat声明中保护起来。

第二个改进:保护Parameters对象的指针instance
static Parameters* Instance() 返回的是个指针,用户可能会调用 delete 操作删除Parameters对象的。做法就是返回一个引用而不是指针,并且将Parameters的析构函数放到 private的声明中,这样拥有 Parameters对象指针者就无法意外删除它了。
改进后的代码如下所示:

未完待续...

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值