在C++中,类的对象建立分为两种,一种是静态建立,如A a;另一种是动态建立,如A* ptr=new A;这两种方式是有区别的。 1、静态建立类对象:是由编译器为对象在栈空间中分配内存,是通过直接移动栈顶指针,挪出适当的空间,然后在这片内存空间上调用构造函数形成一个栈对象。使用这种方法,直接调用类的构造函数。 2、动态建立类对象,是使用new运算符将对象建立在堆空间中。这个过程分为两步,第一步是执行operator new()函数,在堆空间中搜索合适的内存并进行分配;第二步是调用构造函数构造对象,初始化这片内存空间。这种方法,间接调用类的构造函数。

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

容易想到将构造函数设为私有。在构造函数私有之后,无法在类外部调用构造函数来构造类对象,只能使用new运算符来建立对象。然而,前面已经说过,new运算符的执行过程分为两步,C++提供new运算符的重载,其实是只允许重载operator new()函数,而operatornew()函数只用于分配内存,无法提供构造功能。因此,这种方法不可以。 当对象建立在栈上面时,是由编译器分配内存空间的,调用构造函数来构造栈对象。当对象使用完后,编译器会调用析构函数来释放栈对象所占的空间。编译器管理了对象的整个生命周期。如果编译器无法调用类的析构函数,情况会是怎样的呢?比如,类的析构函数是私有的,编译器无法调用析构函数来释放内存。所以,编译器在为类对象分配栈空间时,会先检查类的析构函数的访问性,其实不光是析构函数,只要是非静态的函数,编译器都会进行检查。如果类的析构函数是私有的,则编译器不会在栈空间上为类对象分配内存。因此,将析构函数设为私有,类对象就无法建立在栈上了

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

上述方法的缺点:

一、无法解决继承问题。如果A作为其它类的基类,则析构函数通常要设为virtual,然后在子类重写,以实现多态。因此析构函数不能设为private。还好C++提供了第三种访问控制,protected。将析构函数设为protected可以有效解决这个问题,类外无法访问protected成员,子类则可以访问。 二、类的使用很不方便,使用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运算符就可以实现类对象只能建立在栈上。虽然你不能影响new operator的能力(因为那是C++语言内建的),但是你可以利用一个事实:new operator 总是先调用 operator new,而后者我们是可以自行声明重写的。因此,将operator new()设为私有即可禁止对象被new在堆上

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

参考:《More Effective C++》条款27:如何让类对象只在栈(堆)上分配空间?_彦祖老师-CSDN博客_如何限制一个类对象只能在堆(栈)上分配空间

c++如何让类对象只能在堆(栈)上分配空间相关推荐

  1. [转载]如何限制一个类对象只在栈(堆)上分配空间?

    一般情况下,编写一个类,是可以在栈或者堆分配空间.但有些时候,你想编写一个只能在栈或者只能在堆上面分配空间的类.这能不能实现呢?仔细想想,其实也是可以滴. 在C++中,类的对象建立分为两种,一种是静态 ...

  2. 如何让类对象只在栈(堆)上分配空间?(转)

    参考:http://blog.csdn.net/hxz_qlh/article/details/13135433 只在堆上分配:将析构函数设为私有: 只在栈上分配:将operator new设为私有. ...

  3. 求你了,别再说Java对象都是在堆内存上分配空间的了!

    Java作为一种面向对象的,跨平台语言,其对象.内存等一直是比较难的知识点,所以,即使是一个Java的初学者,也一定或多或少的对JVM有一些了解.可以说,关于JVM的相关知识,基本是每个Java开发者 ...

  4. 对象可以在栈上分配空间吗?_Java面试题之:Java中所有的对象都分配在堆中吗?...

    JVM中的内存划分暂不讨论,单说堆(Heap),堆中一般存放的是new出来的对象.但是,随着JIT(即时编译)编译器的发展与逃逸分析(Escape Analysis)技术逐渐成熟,栈上分配.标量替换优 ...

  5. 只能在堆或只能在栈上分配内存的类

    只能在堆上分配内存的类 方法:将析构函数设置为私有 原因:C++ 是静态绑定语言,编译器管理栈上对象的生命周期,编译器在为类对象分配栈空间时,会先检查类的析构函数的访问性.若析构函数不可访问,则不能在 ...

  6. Java对象都是在堆上分配空间吗?答案竟然是...

    作者 l Hollis 来源 l Hollis(ID:hollischuang) Java作为一种面向对象的,跨平台语言,其对象.内存等一直是比较难的知识点,所以,即使是一个Java的初学者,也一定或 ...

  7. 3704对象关闭时_JVM 通过逃逸分析就能让对象在栈上分配?没那么简单!

    本文转载自公众号 星哥笔记 作者:Danny姜 校对:承香墨影 经常会有面试官会问一个问题:Java 中的对象都是在"堆"中创建吗? 然后跟求职者大谈特谈「逃逸分析」,说通过「逃逸 ...

  8. JVM对象内存分配详细过程(栈上分配->TLAB->老年代->Eden区)

    一个类创建实例的时候,需要经过多个步骤,比如我们调用new的时候经过了哪些流程,本文就来详细分析下 专业术语 逃逸分析算法 逃逸分析其实就是分析java对象的动态作用域, 如果一个对象被定义之后,被外 ...

  9. java创建对象时分配内存方式,是堆上分配还是栈上分配?

    创建对象的内存是分配在堆上还是栈上面?大部分童鞋的回答是这样的:"肯定分配在堆内存的嘛,栈内存是属于子线程和基本数据类型专用的内存空间,怎么会分配到栈上面呢?",这个回答嘛,也对, ...

  10. Linux如何在栈上分配内存,Java堆与栈内存分配及String小记

    栈内存 堆内存 基础类型,对象引用(堆内存地址) 由new创建的对象和数组, 存取速度快 相对于栈内存较慢 数据大小声明周期必须确定 分配的内存由Java虚拟机自动垃圾回收器管理.动态分配内存大小 共 ...

最新文章

  1. PowerDesigner导出表到word
  2. oracle net manager没有orcl_Oracle-数据库基础知识
  3. 姚期智:中国金融科技发展的真正挑战是什么?如何解决? 本文作者:温晓桦 2017-09-17 18:31 导语:“在金融科技里面,计算机科学的用途已经从台后走到了台中,对核心金融体系的运作上产生一定的
  4. ASP.NET Core微服务(二)——【ASP.NET Core Swagger配置】
  5. html开发文档工具栏,添加应用栏和工具栏 (HTML)
  6. Oracle 表的移动和索引的重建
  7. ITester软件测试小栈,点击领取你的能量值!
  8. discuz mysql 编码_Discuz!X 下如何使用 Tools 来转换数据库编码
  9. java 中j= i_java中 i = i++和 j = i++ 的区别
  10. 面向对象的编程(上)_方法的重载(overload)练习
  11. 大白菜无法打开计算机硬盘,大白菜pe系统检测不到硬盘怎么办?
  12. java9推迟_甲骨文宣布Java 9将会推迟到明年7月发布
  13. iOS9.0 canOpenURL: failed for URL: xx - error:This app is not allowed to query for scheme xx
  14. gc buffer busy的优化
  15. android窗帘拉开动画,H5+CSS3窗帘拉开收起动画特效源码
  16. Android源码学习------SystemUI(二)
  17. 网格顶点法向量从世界坐标到切空间坐标转换:法向贴图高低模烘焙
  18. 苹果手机没有备份怎么恢复照片?
  19. linux下$0是什么含义,echo $? 这个东东$?在linux系统里是什么含义?
  20. json数据和对象的区别

热门文章

  1. lr_save_var() 截取任意字符串长度,以参数形式输出(参数转变量)
  2. Java 视频生成缩略图教程
  3. 细说进程、应用程序域与上下文之间的关系(三)—— 深入了解.NET上下文
  4. Oracle中级篇-物化视图
  5. 不同网段windows远程linux桌面,实现不同网段pc机及交换机互通
  6. phpstom怎样导出数据库_用phpStorm的数据库工具来管理你的数据库
  7. 电商网站前台模板_电商热潮汹涌,兴长信达PEC零售商城系统为企业注入新力量...
  8. ELK logstash基本配置
  9. 佳能ts9020墨盒不识别_佳能打印机哪一款性价比高 佳能打印机型号推荐【详解】...
  10. This project uses AndroidX dependencies, but the ‘android.useAndroidX‘ property is not enabled