如何定义一个只能在堆上(栈上)生成对象的类?

在C++中,类的对象建立分为两种,一种是静态建立,如A a;另一种是动态建立,如A* ptr=new A;这两种方式是有区别的。

        静态建立一个类对象,是由编译器为对象在栈空间中分配内存,是通过直接移动栈顶指针,挪出适当的空间,然后在这片内存空间上调用构造函数形成一个栈对象。使用这种方法,直接调用类的构造函数。

        动态建立类对象,是使用new运算符将对象建立在堆空间中。这个过程分为两步,第一步是执行operator new()函数,在堆空间中搜索合适的内存并进行分配;第二步是调用构造函数构造对象,初始化这片内存空间。这种方法,间接调用类的构造函数。

        那么如何限制类对象只能在堆或者栈上建立呢?下面分别进行讨论。

 

1、只能建立在堆上

        类对象只能建立在堆上,就是不能静态建立类对象,即不能直接调用类的构造函数。

        容易想到将构造函数设为私有。在构造函数私有之后,无法在类外部调用构造函数来构造类对象,只能使用new运算符来建立对象。然而,前面已经说过,new运算符的执行过程分为两步,C++提供new运算符的重载,其实是只允许重载operator new()函数,而operator()函数用于分配内存,无法提供构造功能。因此,这种方法不可以。

        当对象建立在栈上面时,是由编译器分配内存空间的,调用构造函数来构造栈对象。当对象使用完后,编译器会调用析构函数来释放栈对象所占的空间。编译器管理了对象的整个生命周期。如果编译器无法调用类的析构函数,情况会是怎样的呢?比如,类的析构函数是私有的,编译器无法调用析构函数来释放内存。所以,编译器在为类对象分配栈空间时,会先检查类的析构函数的访问性,其实不光是析构函数,只要是非静态的函数,编译器都会进行检查。如果类的析构函数是私有的,则编译器不会在栈空间上为类对象分配内存。

        因此,将析构函数设为私有,类对象就无法建立在栈上了。代码如下:

[cpp] view plaincopyprint?
  1. class  A  
  2. {  
  3. public :  
  4.     A(){}  
  5.     void  destory(){ delete   this ;}  
  6. private :  
  7.     ~A(){}  
  8. };  

        试着使用A a;来建立对象,编译报错,提示析构函数无法访问。这样就只能使用new操作符来建立对象,构造函数是公有的,可以直接调用。类中必须提供一个destory函数,来进行内存空间的释放。类对象使用完成后,必须调用destory函数。

        上述方法的一个缺点就是,无法解决继承问题。如果A作为其它类的基类,则析构函数通常要设为virtual,然后在子类重写,以实现多态。因此析构函数不能设为private。还好C++提供了第三种访问控制,protected。将析构函数设为protected可以有效解决这个问题,类外无法访问protected成员,子类则可以访问。

        另一个问题是,类的使用很不方便,使用new建立对象,却使用destory函数释放对象,而不是使用delete。(使用delete会报错,因为delete对象的指针,会调用对象的析构函数,而析构函数类外不可访问)这种使用方式比较怪异。为了统一,可以将构造函数设为protected,然后提供一个public的static函数来完成构造,这样不使用new,而是使用一个函数来构造,使用一个函数来析构。代码如下,类似于单例模式:

[cpp] view plaincopyprint?
  1. class  A  
  2. {  
  3. protected :  
  4.     A(){}  
  5.     ~A(){}  
  6. public :  
  7.     static  A* create()  
  8.     {  
  9.         return   new  A();  
  10.     }  
  11.     void  destory()  
  12.     {  
  13.         delete   this ;  
  14.     }  
  15. };  

        这样,调用create()函数在堆上创建类A对象,调用destory()函数释放内存。

 

2、只能建立在栈上

        只有使用new运算符,对象才会建立在堆上,因此,只要禁用new运算符就可以实现类对象只能建立在栈上。将operator new()设为私有即可。代码如下:

[cpp] view plaincopyprint?
  1. class  A  
  2. {  
  3. private :  
  4.     void * operator  new ( size_t  t){}      // 注意函数的第一个参数和返回值都是固定的   
  5.     void  operator  delete ( void * ptr){}  // 重载了new就需要重载delete   
  6. public :  
  7.     A(){}  
  8.     ~A(){}  
  9. }; 

 

参考资料:

  1. http://www.nowcoder.com/questionTerminal/0a584aa13f804f3ea72b442a065a7618

转载于:https://www.cnblogs.com/vincently/p/4838283.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/458834.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

canny算子的理论分析

****************************************************************************************************************************************** 红:数字图像处理视频教程(两部) {中科院版36讲视频教程 电子科大版70讲视频教程&#x…

Android为spinner设置适配器,Android Spinner与适配器模式详解及实例代码

最近做项目对Android Spinner 使用,这里简单写个小例子,来测试如何使用。Spinner是一个下拉列表,往安卓界面中拖拽一个Spinner控件,在属性中设置Android:entries“array/spinner_data”其中spinner_data为在string中设置的数组。数…

web框架-Struts开始

问题: 为什么有structs 作为一种框架(frameset)可以与传统的mvc进行比较? MVC是一种模式数据处理、显示和数据输入分开,来规范开发,但是却又并不规范。可以这样想:有三家公司,他们对…

加快上架方法

估计最近苹果app应用上架的比较多,审核比较慢,现在一个app从提交到上架短则7,8天,长则2,3个星期。我在实际上线应用时,总结了一个简单实用的小技巧,可以加快上架时间,最近使用这种方…

接口自动化测试 返回html,接口自动化测试实战(更新完毕)

前言自动化没练习的项目怎么办?自动化已经成为测试的必备技能之一了,所以,很多想跳槽的测试朋友都在自学,特别是最实用的接口自动化,但是很多人因为没有可以练手的项目而苦恼,最终导致缺乏实战经验&#xf…

Opencv 图像增强算法 图像检测结果及代码

****************************************************************************************************************************************** 红:数字图像处理视频教程(两部) {中科院版36讲视频教程 电子科大版70讲视频教程&#x…

php Hash Table(四) Hash Table添加和更新元素

HashTable添加和更新的函数: 有4个主要的函数用于插入和更新HashTable的数据: int zend_hash_add(HashTable *ht, char *arKey, uint nKeyLen,void **pData, uint nDataSize, void *pDest); int zend_hash_update(HashTable *ht, char *arKey, uint nKeyLen, void …

山寨“饿了么”应用中添加菜品数量按钮效果

山寨“饿了么”应用中添加菜品数量按钮效果 本人视频教程系类 iOS中CALayer的使用 最终效果: 山寨源头: 源码:(此源码解决了重用问题,可以放心的放在cell中使用) AddAndDeleteButton.h 与 AddAndDeleteBu…

html间数据传送,Express框架与html之间如何进行数据传递(示例代码)

关于Node.js 的Express框架介绍,推荐看菜鸟教程的Express框架,很适合入门,这里不再赘述,这里主要讲一下Express框架与html之间如何进行数据传递我采用的是JQuery的Ajax()向后台传参方式(url传参)1、Type属性为Get时:(1…

数字图像去噪典型算法及matlab实现

图像去噪是数字图像处理中的重要环节和步骤。去噪效果的好坏直接影响到后续的图像处理工作如图像分割、边缘检测等。图像信号在产生、传输过程中都可能会受到噪声的污染,一般数字图像系统中的常见噪声主要有:高斯噪声(主要由阻性元器件内部产…

pat1100. Mars Numbers (20)

1100. Mars Numbers (20) 时间限制400 ms内存限制65536 kB代码长度限制16000 B判题程序Standard 作者CHEN, YuePeople on Mars count their numbers with base 13: Zero on Earth is called "tret" on Mars.The numbers 1 to 12 on Earch is called "jan, feb, …

【USACO1.1】Broken Necklace

题意 一个环形项链,有rbw三种珠子,r代表red,b代表blue,w代表white,从任意一个位置断开,两端分别取珠子,同一端取的珠子要相同颜色,w可以染成想要的颜色,即既可当作r也可以…

html+注释格式化,使用xml注释来生成格式化的html输出

我试图从我在xml文件中的注释中生成一个格式良好的html文档。目前我有一个xml文件,用于生成xml表格的html列表。为了让我添加有关表格的评论,我手动将注释添加到输出html文件中。使用xml注释来生成格式化的html输出我想如果可能将html代码放在xml文件中作…

图像增强-图像锐化

图像锐化主要影响图像中的低频分量,不影响图像中的高频分量。 图像锐化的主要目的有两个: 1.增强图像边缘,使模糊的图像变得更加清晰,颜色变得鲜明突出,图像的质量有所改善,产生更适合人眼观察和识别的图像…

[译]git revert

git revert git revert用来撤销一个已经提交了的快照. 但不是从项目历史中移除这个commit, 而是生成一个新的commit, 老的commit还是保留在历史项目里面的. 这样做的好处是防止了项目丢失历史. 用法 git revert <commit>生成一个新的commit, 撤销老的<commit>的所有…

图像二值化算法总结

****************************************************************************************************************************************** 红&#xff1a;数字图像处理视频教程&#xff08;两部&#xff09; {中科院版36讲视频教程 电子科大版70讲视频教程&#xff…

html 替换反斜杠,在URL直接替换反斜杠反斜杠

我们有一个系统&#xff0c;基于Moodle的平台&#xff0c;在这里的文件是这样引用&#xff1a;在URL直接替换反斜杠反斜杠的http&#xff1a;// [服务器] /file.php/3/LR4/info/ index.html的现在&#xff0c;这个伟大的工程&#xff0c;但是我们的一些老师错误地使用落后的斜杠…

VMware桥接模式无法连网

2019独角兽企业重金招聘Python工程师标准>>> #VMware桥接模式无法连网 在VMware上装了个CentOS7&#xff0c;使用桥接模式连网&#xff0c;开始使用的时候没有问题&#xff0c;可以正常上网。最近打开的时候发现上不了网了&#xff0c; 使用ifconfig查看也没有分配到…

Java 7 中 NIO.2 的使用——第四节 文件和目录

Files类提供了很多方法用于检查在于你真正实际去操作一个文件或目录。这些方法强烈推荐&#xff0c;也非常有用&#xff0c;也能避免很多异常的发生。例如&#xff0c;一个很好的习惯就是在你试着移动一个文件从一个地方到另一个地方的时候&#xff0c;先检查文件是否存在。 检…

计算机二级access知识点6,2019年计算机二级ACCESS考试知识点:关系数据模型

【导语】2019年计算机二级考试备考正在进行中&#xff0c;为了方便考生及时有效的备考&#xff0c;那么&#xff0c;无忧考网为您精心整理了2019年计算机二级ACCESS考试知识点&#xff1a;关系数据模型&#xff0c;欢迎大家的关注。如想获取更多计算机二级考试的备考资料&#…