C++ 私有构造函数的作用

分类: C/C++ 2012-05-08 16:07 1536人阅读 评论(1) 收藏 举报
c++classdeleteobjectvector编译器

很多情况下要求当前的程序中只有一个object。例如一个程序只有一个和数据库的连接,只有一个鼠标的object。通常我们都将构造函数的声明置于public区段,假如我们将
其放入private区段中会发生什么样的后果?这意味着什么?
      当我们在程序中声明一个对象时,编译器为调用构造函数(如果有的话),而这个调用将通常是外部的,也就是说它不属于class对象本身的调用,假如构造函数是私有的,
由于在class外部不允许访问私有成员,所以这将导致编译出错。
      然而,对于class本身,可以利用它的static公有成员,因为它们独立于class对象之外,不必产生对象也可以使用它们。
      此时因为构造函数被class私有化,所以我们要创建出对象,就必须能够访问到class的私有域;这一点只有class的成员可以做得到;但在我们建构出其对象之前,怎么能利用它的成员呢?static公有成员,它是独立于class对象而存在的,“我们”可以访问得到。假如在某个static函数中创建了该class的对象,并以引用或者指针的形式将其返回(这里不以对象返回,主要是构造函数是私有的,外部不能创建临时对象),就获得了这个对象的使用权。
      下面是例子:

[cpp] view plaincopy
  1. <span style="font-family:SimSun;font-size:16px;">class OnlyHeapClass
  2. {
  3. public:
  4. static OnlyHeapClass* GetInstance()
  5. {
  6. // 创建一个OnlyHeapClass对象并返回其指针
  7. return (new OnlyHeapClass);
  8. }
  9. void Destroy();
  10. private:
  11. OnlyHeapClass() { }
  12. ~OnlyHeapClass() {}
  13. };
  14. int main()
  15. {
  16. OnlyHeapClass *p = OnlyHeapClass::GetInstance();
  17. ... // 使用*p
  18. delete p;
  19. return 0;
  20. }</span>

这个例子使用了私有构造函数,GetInstance()作为OnlyHeapClass的静态成员函数来在内存中创建对象:由于要跨函数传递并且不能使用值传递方式,所以我们选择在堆上
创建对象,这样即使getInstance()退出,对象也不会随之释放,可以手动释放。
    
      构造函数私有化的类的设计保证了其他类不能从这个类派生或者创建类的实例,还有这样的用途:例如,实现这样一个class:它在内存中至多存在一个,或者指定数量个
的对象(可以在class的私有域中添加一个static类型的计数器,它的初值置为0,然后在GetInstance()中作些限制:每次调用它时先检查计数器的值是否已经达到对象个数的
上限值,如果是则产生错误,否则才new出新的对象,同时将计数器的值增1.最后,为了避免值复制时产生新的对象副本,除了将构造函数置为私有外,复制构造函数也要特别
声明并置为私有。
      如果将构造函数设计成Protected,也可以实现同样的目的,但是可以被继承。

另外如何保证只能在堆上new一个新的类对象呢?只需把析构函数定义为私有成员。
      原因是C++是一个静态绑定的语言。在编译过程中,所有的非虚函数调用都必须分析完成。即使是虚函数,也需检查可访问性。因些,当在栈上生成对象时,对象会自动析构,也就说析构函数必须可以访问。而堆上生成对象,由于析构时机由程序员控制,所以不一定需要析构函数。保证了不能在栈上生成对象后,需要证明能在堆上生成它。这里OnlyHeapClass与一般对象唯一的区别在于它的析构函数为私有。delete操作会调用析构函数。所以不能编译。
       那么如何释放它呢?答案也很简单,提供一个成员函数,完成delete操作。在成员函数中,析构函数是可以访问的。当然detele操作也是可以编译通过。 
void OnlyHeapClass::Destroy() { 
        delete this; 

    构造函数私有化的类的设计可以保证只能用new命令在堆中来生成对象,只能动态的去创建对象,这样可以自由的控制对象的生命周期。但是,这样的类需要提供创建和撤销
的公共接口。
    另外重载delete,new为私有可以达到要求对象创建于栈上的目的,用placement new也可以创建在栈上。

---------------------------------------------------------------------------------------------------------------------------------
还是不懂啊:   
  1.为什么要自己调用呢?对象结束生存期时不就自动调用析构函数了吗?什么情况下需要自己调用析构函数呢?   
  ================================================================   
  比如这样一种情况,你希望在析构之前必须做一些事情,但是用你类的人并不知道,    那么你就可以重新写一个函数,里面把要做的事情全部做完了再调用析构函数。   这样人家只能调用你这个函数析构对象,从而保证了析构前一定会做你要求的动作。   
    
  2.什么情况下才用得着只生成堆对象呢?   
  ================================   
  堆对象就是new出来的,相对于栈对象而言。什么情况下要new,什么情况下在栈里面    提前分配,无非就是何时该用动态,何时该用静态生成的问题。这个要根据具体情况   
  具体分析。比如你在一个函数里面事先知道某个对象最多只可能10个,那么你就可以定义这个对象的一个数组。10个元素,每个元素都是一个栈对象。如果你无法确定数字,那么你就可以定义一个这个对象的指针,需要创建的时候就new出来,并且用list   或者vector管理起来。

---------------------------------------------------------------------------------------------------------------------------------
类中“私有”权限的含义就是:私有成员只能在类域内被访问,不能在类域外进行访问。   
    
  把析构函数定义为私有的,就阻止了用户在类域外对析构函数的使用。这表现在如下两个方面:   
    
  1.   禁止用户对此类型的变量进行定义,即禁止在栈内存空间内创建此类型的对象。要创建对象,只能用   new   在堆上进行。   
    
  2.   禁止用户在程序中使用   delete   删除此类型对象。对象的删除只能在类内实现,也就是说只有类的实现者才有可能实现对对象的   delete,用户不能随便删除对象。如果用户想删除对象的话,只能按照类的实现者提供的方法进行。   
    
  可见,这样做之后大大限制了用户对此类的使用。一般来说不要这样做;通常这样做是用来达到特殊的目的,比如在   singleton   的实现上。楼主可查找   singleton   的资料来了解它是怎么一回事。

C++ 私有构造函数的作用相关推荐

  1. C#构造函数、私有构造函数、静态构造函数与构造函数执行顺序

    https://www.cnblogs.com/ArtofDesign/p/3603986.html 默认构造函数,如果没有为类指定任何构造函数,编译器会自动为类创建一个无参构造函数,用以初始化类的字 ...

  2. [再读书]私有构造函数

    记录下来,给新手看(应该有人用的到). 私有构造函数初看起来没有什么作用,但是在.net中功能相当多.一般用在许多静态方法的类中,这些静态方法用作一个库,而不是对象.添加私有构造函数,将确保类不能在外 ...

  3. Java性能优化(3):通过私有构造函数强化不可实例化的能力

    有时候你可能会编写出只包含静态方法和静态域的类,这样的类有一些很不好的名声,因为有些人在面向对象的语言中滥用这样的类来编写过程化的程序.尽管如此,它们也确实有它们特有的用处,我们可以利用这种类,把操作 ...

  4. C++之保护和私有构造函数与析构函数

    2019独角兽企业重金招聘Python工程师标准>>> 一.构造函数 1.保护 构造函数定义为protected后,就意味着你不能在类的外部构造对象了,而只能在外部构造该类的子类的对 ...

  5. C#中构造函数的作用

    C#中构造函数的作用 共同点: 都是实例化对象,初始化数据的 默认构造是说所有的类都从祖先object那继承了空参的构造方法,你不写与写空参构造都存在,而有参数的构造一般是自己写的,写就有不写就没有, ...

  6. [转]默认构造函数的作用

    构造函数主要用来初始化对象.它又分为静态(static)和实例(instance)构造函数两种类别.大家应该都了解如果来写类的构造函数,这里只说下默认构造函数的作用,以及在类中保留默认构造函数的重要性 ...

  7. 在php中构造函数的作用,php构造函数的作用

    构造函数的作用是什么?为了让你更好的理解,我举工厂的例子开始讲起: 我们知道,在一个工厂里面,要生产同要求的产品,那么就需要CAD模具.如果引申到我们的PHP中,我们可以理解为类就是CAD模具,决定了 ...

  8. Java私有构造函数不能阻止继承

    下面是一个调用已经私有化的单列的函数的列子. 这里用了静态内部类,关键就是静态内部类可以访问外部类的私有构造函数. 这种算是变种继承吧.前提是可以在原来的单列类里添加代码. class Single ...

  9. 默认构造函数的作用(“A”方法没有采用“0”个参数的重载

    构造函数主要用来初始化对象.它又分为静态(static)和实例(instance)构造函数两种类别.大家应该都了解如何来写类的构造函数,这里只说下默认构造函数的作用,以及在类中保留默认构造函数的重要性 ...

最新文章

  1. linux常用命令及常用快捷键
  2. jsp mysql 分页插件_知识分享:Mybatis框架如何使用分页插件呢?
  3. Linux 命令之 userconf -- 设置用户账号
  4. 酷客多小程序受邀参加 中国县域连锁药店发展峰会
  5. java.lang.OutOfMemoryError: PermGen space---先测试
  6. WWDC22 - In App Purchase 更新总结
  7. mac 终端 常用命令
  8. 凉茶配方案终审 加多宝赔偿近2亿元
  9. 李彦宏“泼水门”:舆论的狂欢,还是魏则西的葬歌?
  10. ESP8266 驱动1.3寸SH1106 OLED屏幕显示库
  11. 【学习笔记】《卓有成效的管理者》 第四章 如何发挥人的长处
  12. 蓝桥杯--历届真题 最优包含【第十届】【决赛】【B组】
  13. java poi导出excel插入图片
  14. 驱动你做一件事的动力来源是什么?
  15. 女研究生因压力大欲跳海轻生 民警跳入冰冷海水中救人
  16. 更改HTML提交按钮的名字
  17. foobar_Foobar挑战:Google对开发人员的隐藏测试
  18. 档案馆容灾备份案例分享
  19. Windows 7 天气 小工具 无法连接到服务 解决方案
  20. java上位机开发(java基础)

热门文章

  1. 一个高端大气上档次的壁纸网站,突破你的的审美
  2. 项目用的几种机型参数调查
  3. U3D 场景切换时 脚本对象,GO对象,资源对象的问题
  4. element-vue的简单使用
  5. iOS攻防——(四)class-dump-与-Dumpdecrypted-使用
  6. HTTP基础及基本配置
  7. DDD理论学习系列(1)-- 通用语言
  8. git学习------gt;Git 分支管理最佳实践
  9. 【12306图片验证12小时内被破解,验证安全的出路到底在哪?】
  10. 关于C++默认拷贝构造函数产生的问题的讨论