《more effective c++》条款26 限制类对象的个数
问题:
如何限制类对象的个数?比如1个,10个等等。
方法(1):
将类的构造函数定义为private,那么就无法实例化这个类了。但是如何创建1个对象出来?方法有2种:
1.声明一个友元函数,那么在友元函数中就可以调用构造函数了,创建对象时使用static限制,那么就保证只有一个对象了。类似的定义如下:
class Printer
{
public:
friend Printer& thePrinter();
private:
Printer();
Printer(const Printer& rhs);
};
Printer& thePrinter()
{
static Printer p;
return p;
}
2.定义一个静态成员函数来代替上面的友元函数也是可以达到同样效果的,就是调用时麻烦了些,需要加上类名才能调用函数,但是这也是可以解决的,将类定义在一个命名空间(namespace)中,再using该命名空间即可直接使用函数名来调用了(具体去看如何定义命名空间)。使用命名空间还可以防止出现名字冲突问题,而且将对象声明在函数中的好处是,只有当调用该函数时,对象才会被创建。注意:尽量不要在内联函数中创建静态对象,可能产生多个副本。
class Printer
{
public:
static Printer& thePrinter();//注意这里
private:
Printer();
Printer(const Printer& rhs);
};
Printer& thePrinter()
{
static Printer p;
return p;
}
方法(2):
在类中定义一个静态计数器,通过计数器来限制实例对象的个数,一旦创建超过限制的个数就抛出异常。这貌似更加好用。
如果单例类是作为基类被继承,那么派生类对象中的基类部分也会被统计进去了,比如彩色打印机继承自打印机,而现在有1台打印机,2台彩色打印机,计数器就是3了。显然不符合我们的要求,我们可以通过private构造函数,那么单例类就无法被继承了。
允许对象来去自由
通常情况下,我们希望可以这样:
create Printer1;
use Printer1;
destroy Printer1; create Printer2;
use Printer2;
destroy Printer2;
但是方法(1)并不能支持。但是结合计数器就可以实现了。具体看书 P105中的代码例子。
一个用于对象计数的基类
如果需要多个具体类怎么办?难道一个个去写去实现?其实可以用模板类作为基类来完成这个功能,使用前将设置一下实例个数就可以使用了,具体看书 P107。
《more effective c++》条款26 限制类对象的个数的更多相关文章
- Effective C++ 条款13/14 以对象管理资源 || 在资源管理类中小心拷贝行为
三.资源管理 资源就是一旦你使用了它,将来不用的时候必须归还系统.C++中最常用的资源就是动态内存分配.其实,资源还有 文件描述符.互斥器.图形界面中的字形.画刷.数据库连接.socket ...
- Effective C++ 条款26
尽可能延后变量定义式的出现时间 我们知道定义一个对象的时候有一个不争的事实,那就是分配内存.假设是我们自己定义的对象.程序运行过程中会调用类的构造函数和析构函数. 我们打个例如,假设天下雨了,你带把雨 ...
- Effective C++ -----条款13:以对象管理资源
为防止资源泄漏,请使用RAII(Resource Acquisiton Is Initialization) 对象,它们在构造函数中获得资源并在析构函数中释放资源. 两个常被使用的RAII class ...
- Effective C++ 条款12:复制对象时勿忘其每一个成分
void logCall(const std::string& funcName); class Customer { public: ... Customer (const Customer ...
- Effective C++ 条款04:确定对象被使用前已经先被初始化
规则一 永远在使用对象之前将它初始化 int x = 0; const char* text = "A C-style string"; double d; std:: cin & ...
- Effective C++ -----条款26:尽可能延后变量定义式的出现时间
尽可能延后变量定义式的出现.这样做可增加程序的清晰度并改善程序效率.
- effective c++ 条款26 postpone variable definition as long as possible
因为构造和析构函数有开销,所以也许前面定义了,还没用函数就退出了. 所以比较好的方法是用到了才定义.
- Effective Objective-C 2.0 — 第14条:理解“类对象“的用意
每个实例都有一个指向Class 对象的指针,用以表明其类型,而这些 Class 对象则构成了类的继承体系. 如果对象类型无法在编译期确定,那么就应该使用类型信息查询方法来探知. 尽量使用类型信息查询方 ...
- MoreEffectiveC++Item35 条款26: 限制某个class所能产生的对象个数
一 允许零个或一个对象 我们知道每当即将产生一个对象,我们有一个constructor被调用,那么我们现在想组织某个对象的产生,最简单的方法就是将其构造函数声明成private(这样做同事防止了这个类 ...
随机推荐
- Front End中Javascript兼容问题收集(转)
1 select标签,就有诸多不兼容: A. cloneNode方法,对于非IE浏览器没有问题,对于IE浏览器, 遇到的问题包括: 1)option selected的会clone不过去,然后 ...
- Java多线程-新特性-有返回值的线程
在Java5之前,线程是没有返回值的,常常为了“有”返回值,破费周折,而且代码很不好写.或者干脆绕过这道坎,走别的路了. 现在Java终于有可返回值的任务(也可以叫做线程)了. 可返回值的任务必须实现 ...
- ecshop数据库取数据
取出所有数据: test_getAll(); function test_getAll() { global $db; $sql = "SELECT user_id, user_name, ...
- Jquery 表格操作,记录分页情况下,每一页中被用户勾选的信息
如下图,一个分页列表,用户可以随意勾选一条或多条信息,然后进行某种操作,如“提交”.但是有个问题:如果勾选了一条信息之后,点[下一页],那么上一页 勾选的条目被刷新掉了. 问题:如果用户需要在第1页, ...
- 10款优秀Vim插件帮你打造完美IDE
导读 如果你稍微写过一点代码,就能知道“集成开发环境”(IDE)是多么的便利.不管是Java.C还是Python,当IDE会帮你检查语法.后台编译,或者自动导入你需要的库时,写代码就变得容易许多.另外 ...
- 时钟 IoTimer
/* 例程是在运行在DISPATCH_LEVEL的IRQL级别 例程中不能使用分页内存 另外在函数首部使用 #pragma LOCKEDCODE */ #include "Driver.h& ...
- NDK JNI 的关键点
1.System.loadLibrary 的名字是在Android.mk里面设定的 LOCAL_MODULE := httpdown,MODULE 后面跟的就是了 2.如何正确调用到关键 ...
- POJ 1850 Code 字符串 难度:1
题意: 1 如果是严格升序的字母字符串,那么可以输出非0解码,否则不能译码输出0 2 字符串解码 遵循递增原则,其值为 到现在为止的所有按字母序小于该字符串的数量 + 1; #include < ...
- Mvc学习--1
1.缓存机制[OutputCache(Duration=10)] 后面的 duration 表示缓存时间 直接放在action上面 是一个特性2.文件上传 @using (Html.BeginForm ...
- 这个setDefaultCloseOperation写不写的区别是什么?
2009-03-23 13:40提问者采纳 设置用户在此窗体上发起 "close" 时默认执行的操作.必须指定以下选项之一: DO_NOTHING_ON_CLOSE(在 W ...