stack对象与heap对象
从高地址到低地址,分别是stack,heap,static object,stack地址往下增长,heap地址往上增长。只要记住:stack栈顶地址反而小,就知道往下增长了。
禁止产生堆对象
1、产生堆对象使用new operator,可认为new operator有三个过程:
a、使用operator new操作符搜索可用的内存,分配一块内存;
b、在这块内存上,调用构造方法构造一个对象;
c、返回地址。
2、要禁止产生堆对象,可以声明类的operator new为private,禁止分配内存就好了。为了保持一致性,将operator delete也重载为private。
3、注意:new operator不能改变它的行为,operator new是可以重载的。
禁止产生栈对象
1、对于栈对象,栈顶指针挪出一块内存,调用构造方法直接构造对象,离开作用域,调用析构方法。
2、因此,要禁止产生栈对象。可以将构造方法或者析构方法声明为private。
3、将构造方法声明为private,那么问题来了,这将导致无法在类的外部使用new 创建堆对象,为什么?
因为new 产生堆对象也要在分配的内存上调用构造方法。private只能在类的内部使用,因此只能在类的内部使用new 创建堆对象,这就需要重新暴露一个接口,返回堆上创建的对象。也就是静态方法GetInstance。注意,这与单例模式不同,单例模式只使用一次new,返回的是同一个对象地址。而当前的情况是,每次调用静态方法,使用new,返回一个新的对象。
4、将构造方法声明为private,必须使用静态方法对外暴露产生的堆对象,同时构造方法有多个,为了禁止产生栈对象,每个都必须声明为private。有没有更好的办法呢?
5、将析构方法声明为private,毕竟析构方法就只有一个。析构方法为private,栈上对象调用构造方法,没有问题,离开作用域,试图调用析构方法,出错了。编译报错。使用new创建对象,没问题。
6、但是有新的问题了,这时候不能使用delete operator释放内存了。为什么?
考虑string* ps; delete ps产生如下的代码:
ps->~string();
operator delete(ps);
这就相当于,在外部使用private 析构方法了。编译当然出错。那该怎么办呢?
7、只能在类的内部使用delete,因此需要重新暴露一个接口Destroy(),Destroy调用delete。
8、将析构方法声明为private,还有一个问题。那就是,导致子类析构的时候无法调用父类的析构方法。怎么办?
将析构方法声明为protected。
stack对象与heap对象的更多相关文章
- JVM系列之:详解java object对象在heap中的结构
目录 简介 对象和其隐藏的秘密 Object对象头 数组对象头 整个对象的结构 简介 在之前的文章中,我们介绍了使用JOL这一神器来解析java类或者java实例在内存中占用的空间地址. 今天,我们会 ...
- java - Stack栈和Heap堆的区别
首先分清楚Stack,Heap的中文翻译:Stack—栈,Heap—堆. 在中文里,Stack可以翻译为“堆栈”,所以我直接查找了计算机术语里面堆和栈开头的词语: 堆存储 ...
- JAVA Stack栈和Heap堆的区别(转)
首先分清楚Stack,Heap的中文翻译:Stack—栈,Heap—堆. 在中文里,Stack可以翻译为“堆栈”,所以我直接查找了计算机术语里面堆和栈开头的词语: ...
- 逻辑运算符、三元运算符、for循环、stack(栈),heap(堆),方法区,静态域
Lesson One 2018-04-17 19:58:39 逻辑运算符(用于逻辑运算,左右两边都是 true 或 false) 逻辑与-& 和 短路与-&& 区别: & ...
- 解释内存中的栈(stack)、堆(heap)和静态区(static area)的用法
堆区:专门用来保存对象的实例(new 创建的对象和数组),实际上也只是保存对象实例的属性值,属性的类型和对象本身的类型标记等,并不保存对象的方法(方法是指令,保存在Stack中) 1.存储的全部是对象 ...
- 栈(stack)和堆(heap)
栈(stack)和堆(heap), Java程序在运行时都要开辟空间,任何软件在运行时都要在内存中开辟空间,Java虚拟机运行时也是要开辟空间的.JVM运行时在内存中开辟一片内存区域,启动时在自己的内 ...
- 如何给女朋友讲明白:Java 中 Stack(栈) 与 Heap(堆)
背景 Java 中 Stack(栈) 与 Heap(堆) 是面试中被经常问到的一个话题. 有没有对 Java 中 Stack(栈) 与 Heap(堆) 烂熟于心的童鞋,请举手!!!(怎么没人举手-) ...
- java中堆栈(stack)和堆(heap)(还在问静态变量放哪里,局部变量放哪里,静态区在哪里.....进来)
(1)内存分配的策略 按照编译原理的观点,程序运行时的内存分配有三种策略,分别是静态的,栈式的,和堆式的. 静态存储分配是指在编译时就能确定每个数据目标在运行时刻的存储空间需求,因而在编 译时就可以给 ...
- 3.2 java中堆栈(stack)和堆(heap)(还在问静态变量放哪里,局部变量放哪里,静态区在哪里.....进来)
(1)内存分配的策略 按照编译原理的观点,程序运行时的内存分配有三种策略,分别是静态的,栈式的,和堆式的. 静态存储分配是指在编译时就能确定每个数据目标在运行时刻的存储空间需求,因而在编 译时就可以给 ...
随机推荐
- linux笔试
在对linux基本知识的归纳总结之后,这里是一份linux的测试题.希望能帮助大家复习和熟悉linux知识. 一.选择题 1.cron 后台常驻程序 (daemon) 用于: A. 负责文件在网络中 ...
- 移动对meta的定义
以下是meta每个属性详解 尤其要注意的是content里多个属性的设置一定要用分号+空格来隔开,如果不规范将不会起作用. 一.<meta http-equiv="Content-Ty ...
- js函数——倒计时模块+无缝滚动
倒计时 效果: 代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset=&qu ...
- How to easily create popup menu for DevExpress treelist z
http://www.itjungles.com/how-to-easily-create-popup-menu-for-devexpress-treelist.html Adding popup m ...
- Dev gridControl 添加表标题
1.OptionsView ->ShowViewCaption = True 2.ViewCaption = "标题"
- 关于ShareSDK接入的各种问题,以及解决方案
随着社交网络的流行,游戏接入分享已经是必然.毕竟这是非常好的一种推广方式.ShareSDK是一个非常好的内分享提供商!但是接入后发生的各种问题,下面给大家提供几个本人遇到的问题,以及解决方法: 1)微 ...
- 在Lua里写unity游戏笔记
gameobject.GetComponent<Transform>(); 翻译成Lua: gameObject:GetComponent (luanet.ctype (Transform ...
- sensor_HAL分析
http://blog.csdn.net/new_abc/article/details/8971807 http://blog.csdn.net/cs_lht/article/details/817 ...
- public private protected和默认的区别(转自百度)
public private protected和默认的区别 Java中对类以及类中的成员变量和成员方法通过访问控制符(access specifier)进行区分控制.刚学Java语言的同学可能对pu ...
- 最大连续子数组问题-homework-01
1)先写我的 github 的介绍: github 的域名:http://www.github.com/zhuifeng1022 登入 github 大概是下面的视图: 按照助教的方法:我已经建好了代 ...