【M26】限制某个class所能产生的对象数量
1、每当产生一个对象,必定调用构造方法。因此,禁止产生对象的做法就是,将所有的构造方法声明为private。
2、只有在类的内部才可以访问private成员,有两层含义:在类的内部可以访问this的private成员,同时可以访问同类对象的private成员。
3、将构造方法声明为private,只是限制了在外部调用构造方法产生对象,还是有办法可以产生对象。办法有:
a、类暴露一个static方法,在static方法内部调用private构造方法,产生对象返回。
b、在类中声明友元方法,或者友元类,这样的话,就可以访问该类的private构造方法。
4、考虑,只产生一个对象。该怎么办?使用友元方法,内部有static对象,返回static对象的引用。比如:只产生一个打印机。
在类中声明:friend Printer& thePrinter();
实现为:
printer& thePrinter()
{
static Printer p;
return p;
}
5、上面的方式有个问题,友元方法是个全局方法,意味着放大了作用域。有没有更好的办法呢?
a、第一个办法是,使用命名空间,将与Printer有关的内容放在这个命名空间内,这样就缩小了作用域。
b、第二个方法是,让类暴露一个static方法。如下:
在类中声明:static Printer& thePrinter();
实现为:
Printer& Printer::thePrinter()
{
static Printer p;
return p;
}
从封装的角度看,类本身表示一个范围,可以认为命名空间的意思。只不过,命名空间内的东西都是public,而类中可以细化为public,protected,private。
6、现在考虑,方法中的static对象。
a、首先一点,对于方法中的static对象,也就是local static对象,方法不被调用,static对象就绝不会产生。而对于non-local static对象(包括全局对象,命名空间内的对象,file作用域,class中的static对象),即使从未被调用,也要构造析构对象。从c++的角度看,不要为不使用的东西产生代价。因此,使用local static对象更好。
b、还有第二点,在一个编译单元内的static对象,C++保证按声明的顺序初始化,而对于不同编译单元内的static对象,顺序是不确定的,因此,程序员不能依赖某种初始化顺序。而对于,方法中的static对象,确定是第一次调用方法的时候,初始化static对象。
c、还有一点,这个方法不能声明为inline,思考为什么?这个方法中,使用static,目的就是,返回的引用都是这个static对象。假如使用inline,可认为编译器在每个调用的地方进行文本替换,这样的话,就会产生多个static对象,这明显不是我们所期望的。
7、现在考虑,更一般化的问题。比如,我们有5个打印机,如何限制产生的对象个数不能大于5?
在类中维护两个字段:已经产生的对象个数NumObjects和允许最多的对象个数MaxObjects,这两个字段对类和所有对象有意义,因此是static。每次构造对象的时候,检查NumObjects<MaxObjects,条件满足,++NumObjects,构造一个新对象返回。条件不满足,抛出一个异常。每次析构对象的时候,--NumObjects。
8、上面的方式,在调用构造方法的时候,对NumObjects累加。这将导致下面的两个问题:
a、考虑,ColorPrinter继承Printer,实例化ColorPrinter对象的时候,会调用Printer 的构造方法,对NumObjects累加,这不是我们所期望的。
b、考虑类A中内含Printer对象,A a1,a2; 导致调用Printer构造方法两次,这也不是我们所期望的。
9、怎么解决上面的问题? 问题的关键是Printer对象在3种状态下生存:a、它自己;b、子类的父类成分中;c、内嵌于其它对象中。因此,解决的办法是,禁止后面的两种状态。也就是将构造方法声明为private。 构造方法声明为private,不能被继承,同时不能在外部调用构造方法构造对象。但同时,又必须产生对象给外部用,也就是上面的方法:类暴露static方法,或者类中声明友元方法或者友元类。
10、考虑下面的问题,如果有很多类似Printer的类,该怎么办呢?
把共用的代码放到父类中,父类负责管理对象的个数,因为可以对不同的类封装,因此父类是模板类。如下:
class Printer: private Counted<Printer>
【M26】限制某个class所能产生的对象数量的更多相关文章
- 2-移远GSM/GPRS M26 模块 Mini板 开发板(M26入门)
https://www.cnblogs.com/yangfengwu/p/11214553.html 资料获取,首先说一下....很多东西需要自己悟,没有QQ群,没有微信群,论坛也寥寥无几!!!! 估 ...
- 1-移远GSM/GPRS M26 模块 Mini板 开发板(使用说明)
板子预览 引脚说明 供电 关于串口电压匹配引脚: 上面一版朋友测试反应的问题 (上面的内容不删除,因为已经出售了1套) 1,源码开发完以后,烧录完成 PWRKEY按键不能使用了,需要断电上电,那么就需 ...
- ListView初探
一.ListView介绍 在Android开发中ListView是比较常用的控件,常用于以列表的形式显示数据集及根据数据的长度自适应显示. ListView通常有两个主要功能点: (1)将数据集填充到 ...
- CSS字体记录
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAaYAAACnCAIAAADVOG9FAAAgAElEQVR4nOy9eXwcxZk/vL/9ve8eb7 ...
- BOOST.Asio——Tutorial
=================================版权声明================================= 版权声明:原创文章 谢绝转载 啥说的,鄙视那些无视版权随 ...
- iOS GCD NSOperation NSThread等多线程各种举例详解(拷贝)
2年多的iOS之路匆匆而过,期间也拜读来不少大神的博客,近来突然为自己一直做伸手党感到羞耻,是时候回馈社会.回想当年自己还是小白的时候,照着一些iOS多线程教程学,也只是照抄,只知其然.不知其所以然. ...
- SQL Server优化技巧之SQL Server中的"MapReduce"
日常的OLTP环境中,有时会涉及到一些统计方面的SQL语句,这些语句可能消耗巨大,进而影响整体运行环境,这里我为大家介绍如何利用SQL Server中的”类MapReduce”方式,在特定的统计情形中 ...
- Spring 框架的设计理念与设计模式分析
转载地址:https://www.ibm.com/developerworks/cn/java/j-lo-spring-principle/ Spring 作为现在最优秀的框架之一,已被广泛的使用,并 ...
- 【js类库Raphaël】基于svg中的path画40%表示的环型图
一.可供参考的文档资料. raphaeljs官网:http://raphaeljs.com/ w3c关于path的介绍:http://www.w3.org/TR/2003/REC-SVG11-200 ...
随机推荐
- ffmpeg windows 雪花声解决方法
替换所有文件里的<math.h>为<mathimf.h>即可. 我用ffmpeg-0.6.3版测试时,好像mathimf.h文件和其他文件有冲突,需要修改源码. 和qdm2.c ...
- 多线程程序设计学习(5)balking模式和timed模式
Balking[返回模式]timed[超时模式]一:balking pattern的参与者--->GuardedObject(被警戒的对象) --->该模式的角色:模拟修改警戒对象的线程, ...
- sql给数据库加锁问题
加锁是在操作数据时进行了,不能事后加锁. 例: begin tran insert 表 with(TABLOCKX) --加锁 (字段列表) ...
- Oracle RAC环境下如何更新patch(Rolling Patch)
Oracle RAC数据库环境与单实例数据库环境有很多共性,也有很多异性.对于数据库补丁的更新同样如此,都可以通过opatch来完成.但RAC环境的补丁更新有几种不同的更新方式,甚至于可以在零停机的情 ...
- Oracle 一次 锁表 处理小记
同事说测试库上的一张表被锁了. 不能执行DML 操作. 锁表的准确说法应该是阻塞.之前的一遍blog里有说明: 锁 死锁 阻塞Latch 等待 详解 http://blog.csdn.net/tian ...
- K2 学习笔记
转:http://www.cnblogs.com/kaixuanpisces/category/149223.html k2 简介 工作流介绍 k2流程设计简介 K2流程设计详细版(图文)一 K2流程 ...
- C 的 coroutine 库 via 云风的 BLOG
今天实现了一个 C 用的 coroutine 库. 我相信这个东西已经被无数 C 程序员实现过了, 但是通过 google 找了许多, 或是接口不让我满意, 或是过于重量. 在 Windows 下, ...
- Android 翻页效果 电子书
转载请注明来自: 5进制空间-android区 相信做电子书的同学,都遇到过翻页动画的需求吧,如果你不满足与点击滑动翻页的话,这边文章应该能够帮助到你. 先上个效果图: 效果还是很不错的,不过与ibo ...
- Android中获取应用程序(包)的信息----PackageManager
本节内容是如何获取Android系统中应用程序的信息,主要包括packagename.label.icon.占用大小等.具体分为两个 部分,计划如下: 第一部分: 获取应用程序的packagena ...
- MySql相关及如何删除MySql服务
又会一招–如何删除MySql服务 进入“控制面板->管理工具->服务”查看才发现,虽然MYSQL已经卸载了,但是MYSQL服务仍然残留在系统服务里.又不想改服务名,改怎么办呢. 后来上百度 ...