关于构造单实例类的一个问题

2016-01-29 12:19 15 1 收藏

关于构造单实例类的一个问题,关于构造单实例类的一个问题

【 tulaoshi.com - C语言心得技巧 】

关于构造单实例类的一个问题


作者/NorthTibet

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com)

下载源代码

   最近一个朋友问我创建单实例的一个问题,他写了一个C++单实例类CSingleton,其构造函数也是private类型。这个类有一个静态函数:GetInstance,它返回单实例类对象的引用,只要用这个函数声明实例便可以限制对象的复制:

// 这一句编译器通不过 CSingleton temp = CSingleton::GetInstance();      
但是编译器始终在上面这行代码处受阻。这到底是为什么呢?
    其实,这个问题只要弄清楚编译器处理单实例类的一些细节,问题便会迎刃而解。当编译器碰到上面的这条语句时,它会去寻找类的拷贝构造函数,所谓的拷贝构造函数,就是一个署名为CSingleton(const CSingleton&)的构造函数。如果你没有提供这个拷贝构造函数,那么C++编译器会为你提供一个默认的拷贝构造函数。这个默认的拷贝构造函数做的事情很简单,只是将字节从一个对象靠到另一个对象。如果你想这个拷贝构造函数它干点别的什么事情,你必须实现自己的拷贝构造函数。为了限制对象的复制,还必须使这个拷贝构造函数为private类型:
class CSingleton {private:  // 私有类型的拷贝构造函数  CSingleton(const CSingleton& obj)   { ASSERT(FALSE); } // should never happen};
此外,你还必须实现默认的构造函数,也就是不带参数的构造函数,如果没有默认的构造函数,你将不能创建对象实例。默认的构造函数可以是private类型,也可以是protected类型,这要看你是不是想要从CSingleton派生其它的类。总而言之,要想正确创建单实例类,下面的这些原则或诀窍对你是有帮助的: 创建默认构造函数、拷贝构造函数和赋值操作符,并且它们的类型都为私有类型。 创建一个静态函数GetInstance,用它来返回唯一的对象实例 下面是一个具体的例子代码:
// 如果你编译这个程序,会产生错误。参见main函数的注释// class CSingleton {public:   static CSingleton& GetInstance() {      static CSingleton theInstance; // 唯一实例      return theInstance;   }protected:   // 需要默认的构造函数ctor   // 因为要创建派生类,ctor 为 protected 类型    CSingleton() { }private:   CSingleton(const CSingleton& o) { }   CSingleton& operator=(const CSingleton& o) { }}; void main(){    // 由于构造函数是私有类型的,所以这几行编译通不过:    CSingleton x = CSingleton::GetInstance(); // error: private                    // copy ctor!    CSingleton y = CSingleton::GetInstance(); // error: private                    // copy ctor!    x = y;         // error: private                    // assignment!    // 编译器看到这样的实例声明会更满意一些:    CSingleton *p1 = CSingleton::GetInstance();    CSingleton *p2 = p1->GetInstance();    CSingleton & ref = * CSingleton::GetInstance();}      
参考文章:
单实例设计模式的实现 如何保证在应用程序使用的类只有一个对象实例?

来源:https://www.tulaoshi.com/n/20160129/1485603.html

延伸阅读
标签: Web开发
?//目录操作基类class FileDirectory { var $servermode; var $serverpath; //web服务器目录 var $pagepath; //当前页目录 var $path; //当前目录 var $ffblk; //用于存储有关文件的信息 function FileDirectory() { set_time_limit(0); //设置网页运行时间,0不限 $this-serverpath = $GLOBALS[DOCU...
标签: Web开发
HTML  HEAD   SCRIPT LANGUAGE="JavaScript"   !--  var Drag = {   sx : 0,   sy : 0,   ex : 0,   ey : 0,   lx : 0,   ly : 0,   offsetX : 0,   offsetY : 0,   cdom : null,   dragAble : false,   dragFun : null,   tempDrag : function(){  &nb...
标签: Web开发
基本用法: 代码如下: var ajax = new AjaxObj(url); ajax.addListener(200, function(r){ alert(r); }); ajax.send(); 也可以连续调用: 代码如下: var ajax = new AjaxObj(url).addListener(200, function(r){ alert(r); }).send(); 另外还支持自定义的POST或GET方式请求,以及监视不同的HTTP状态码,自己看代码琢磨...
标签: Web开发
结合一个存储过程,将分页做成最简单,请看以下源码 此分页类所操作的存储过程#region 此分页类所操作的存储过程 /**//*********************************************************  *  * 功能强大,配合以下这个存储过程  *  * *******************************************************...
  函数功能:该函数获得一个窗口的句柄,该窗口的类名和窗口名与给定的字符串相匹配。这个函数查找子窗口,从排在给定的子窗口后面的下一个子窗口开始。在查找时不区分大小写。     函数原型:HWND FindWindowEx(HWND hwndParent,HWND hwndChildAfter,LPCTSTR lpszClass,LPCTSTR lpszWindow); ...

经验教程

315

收藏

72
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部