http://www.cnblogs.com/chio/archive/2007/10/23/934335.html

http://blog.csdn.net/szchtx/article/details/12000867

在C++中,类的对象建立分为两种,一种是静态建立,如A a;另一种是动态建立,如A* ptr=new A;(ptr是栈上变量,指向堆中空间)这两种方式是有区别的。

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

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

1、只能建立在堆上:(将构造函数、析构函数声明为private,然后将new、delete封装在静态成员函数中,通过静态成员函数的调用来实例化对象和销毁对象)

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

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

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

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

class A
{
public:A(){}void destory(){delete this;}
private:~A(){}
};

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

将析构函数声明为private,类的用户不能定义类对象,但是友元或类成员函数可以使用,为了防止友元或类成员函数使用,可以将析构函数只声明不定义,这样若类的用户定义类对象,编译时出错,成员函数或友元定义类对象,链接时出错,此处不用考虑友元和成员函数,只是要求类用户不能静态建立对象。

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

class A
{
protected:A(){}~A(){}
public:static A* create()//可以用类名来调用,非静态成员函数不能用类名调用{return new A();}void destory(){delete this;}
};

2、只能建立在栈上

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

class A
{
private:void* operator new(size_t t){}     // 注意函数的第一个参数和返回值都是固定的,new的参数是new的运算对象void operator delete(void* ptr){} // 重载了new就需要重载delete
public:A(){}~A(){}
};

转载于:https://www.cnblogs.com/ljygoodgoodstudydaydayup/p/3897336.html

【c++】【转】如何只在heap上创建对象,如何只在stack上建立对象?相关推荐

  1. C++:在堆上创建对象,还是在栈上?

    这篇文章来自于一次讨论:http://www.devbean.net/2013/01/qt-study-road-2-model-view/#comment-17532.关于究竟是在堆上还是在栈上创建 ...

  2. 只能在栈上或者堆上创建对象

    只允许对象生成于堆内?怎么理解?肿么办?假如,手头上有一个类Person,当你在程序中写下Person rn时,编译器悄悄地做了两件事:调用constructor构造对象rn,而在弹栈时,调用dest ...

  3. C++ 如何一次在堆上申请4G的内存?如何设计一个类只能在堆或者栈上创建对象?

    1.如何一次在堆上申请4G的内存? 因为32位的环境下虚拟地址空间的大小只有4g,而光内核空间就需要1g,所以不可能申请得到,只有在64位的环境下才可以实现,只需要把执行环境改为64x即可 #incl ...

  4. django文件上传,只上传一张

    并发条件下对于一个对象的不同图片进行操作,导致只有一张生效 class PersonalId(models.Model):imageface = models.ImageField(null=True ...

  5. 【题目】一根长度为M厘米的木棍上有n只蚂蚁,每只蚂蚁要么朝左爬,要么朝右爬,速度为每秒1厘米。当两只蚂蚁对撞时,二者同时掉头(掉头时间忽略不计)。给出每只蚂蚁的初始位置和朝向,计算T秒后每只蚂蚁的位置

    文件名:[作业] 作者:〈漆黑〉 描述:〈 一根长度为M厘米的木棍上有n只蚂蚁,每只蚂蚁要么朝左爬,要么朝右爬,速度为每秒1厘米.当两只蚂蚁对撞时,二者同时掉头(掉头时间忽略不计).给出每只蚂蚁的初始 ...

  6. 狡猾的老鼠 -有一只狡猾的老鼠,在一个环形的田埂上挖了n个老鼠洞,这些洞也是连接为一个环状,我们要用泥土填满这些鼠洞,老鼠从第0号洞开始出现(第0号洞不填),然后依次按每间隔m个洞出现一次。我们要跟在

    问题描述 有一只狡猾的老鼠,在一个环形的田埂上挖了n个老鼠洞,这些洞也是连接为一个环状,我们要用泥土填满这些鼠洞,老鼠从第0号洞开始出现(第0号洞不填),然后依次按每间隔m个洞出现一次.我们要跟在老鼠 ...

  7. 电脑常识:连不上网络,只显示飞行模式?

    电脑常见问题:连不上网络,只显示飞行模式 有的时候,我们突然打开笔记本,会发现电脑突然就连不上网了,各种重启电脑都没用,是怎么回事啊?并且显示只有飞行模式,但是飞行模式并未开启啊,且网络状态显示未连接 ...

  8. 比亚迪追上特斯拉,只差半个涨停和一个智能化?

    比亚迪距离追上宁德时代,就差半个涨停. 近日,比亚迪市值一度突破万亿,超越大众.宝马.通用.福特等老牌车企,成为全球第三家市值超过1500亿美元的车企.有人调侃:"这是宁王和迪王交接了吗?& ...

  9. casio学生用计算机怎么显示数字,CASIO学生用计算机显示频右上角上出现FIX 只需教我按键就行了...

    CASIO学生用计算机显示频右上角上出现FIX 只需教我按键就行了以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! CAS ...

最新文章

  1. js 刷新页面但是不闪烁_前端开发还在手动刷新页面?手把手教你搭建一个自动刷新工具...
  2. 大学计算机思维导图_我学计算机,也会修电脑
  3. Delphi开发的IOCP测试Demo以及使用说明。
  4. 年薪不到 25.2 万免费学,廖雪峰的“大数据高级开发”课程第5期开始招生
  5. HP-UX 六大虚拟化技术之“分区”
  6. Ubuntu 16.04安装XMind 8
  7. HTML引入第三方类库项目需要授权解决方案
  8. EFCore.Sharding(EFCore开源分表框架)
  9. 开关灯(jzoj 3926)
  10. 数据结构之栈与递归的应用(汉诺塔递归解法)
  11. DDOS高防IP作用,哪些地方需要用到高防IP
  12. 【实战案例】利用Python做出趣味版防沉迷小程序
  13. ARCore快速入门--在模拟器(Emulator)上运行AR应用
  14. 利用记事本编写html代码和word实现A4信笺纸(信签纸)电子版的两种设计法
  15. HTML5 video(PC和移动端)自动播放学习指北
  16. leetcode 73 矩阵归零
  17. JavaWeb学习笔记(七)—— JSP
  18. 李宏毅机器学习L6 GAN
  19. source insight4.0使用教程
  20. [转]自定义Drawable实现灵动的红鲤鱼动画(上篇)

热门文章

  1. iPhone开源系列:iDev Recipes
  2. 卓瑞机器人_校企合作专业共建记涪陵职教中心机器人专业中泰学术交流活动
  3. modelsim 自动化 独立仿真vivado ip核工程
  4. mysql数据库映射到内存_基于共享内存的数据库映射
  5. 关于示波器地线的问题!
  6. 极光推送配置(Android Studio),亲测有效
  7. Google跨平台UI框架 Flutter beta 重磅发布,这里有你需要了解的一切
  8. zabbix3.2.6.1升级3.4.4图文心得
  9. 第十六周项目3:max带来的冲突
  10. gst-rtsp-server编译测试