1、要求对象只能产生于heap之中,该怎么办?

  栈上的对象肯定调用构造方法和析构方法(离开作用域的时候),因此,要求对象只能产生于heap之中,也就是禁止栈上产生对象,解决办法有两种:将所有的构造方法声明为private,或者将析构方法声明为private。

2、将所有的构造方法声明为private,这样就不能在栈上构造对象了。这有两点需要注意:

  a、这种情况下,不能在外部使用new operator在堆上构造对象,因为new operator要在分配的内存上,调用构造方法构造对象。因此,需要重新暴露接口,返回堆上的对象。办法有:在类内部使用new operator,暴露static方法;使用友元方法或者友元类。

  b、一个类往往有多个构造方法,必须将所有的构造方法都声明为private。对于default 构造方法,如果没有声明任何构造方法,编译器会自动生成一个。对于copy构造,没有声明,编译器也会自动生成一个。

3、将析构方法声明为private,由于栈对象离开作用域,会自动调用析构方法,出现错误,在编译时就报错。这有两点需要注意:

  a、这种情况下,不能在外部使用delete operator删除指针,因为delete operator要调用析构方法,然后调用operator delete释放内存。因此,需要重新暴露接口,Destroy方法,在Destroy方法内部调用delete operator。

  b、相比于构造方法,析构方法只有一个,只需要将这一个析构方法声明为private就好了。

4、需要注意,将构造方法或者析构方法声明为private,将导致两个问题,那就是继承和内含,这两种情况都要调用构造方法和析构方法。

  对于继承,可以将父类的构造方法和析构方法放大访问权限,为protected。

  对于内含一个对象,修改为内含一个指针,指向对象。使用其他暴露的借口,获取堆上的对象和释放内存(Destroy)。

5、考虑下面的问题,如何判断某个对象是否位于heap内?

6、我们知道,在堆上创建对象必定调用operator new分配内存,因此,可以在operator new调用的时候,标识将要产生的对象在堆上,对象构造后,然后清除标识。这有两个问题:a、对于数组,使用operator new[],一次性分配多个内存,只有第一个对象是分配在堆上。b、考虑new UPNumber(* new UPNumber),C++的执行顺序可能是先调用两次operator new,在调用两次构造方法,导致上述的办法失效。

7、C++程序的内存布局,从高到低以此为stack,heap,静态存储区,stack向下增长,heap向上增长。在栈上创建一个对象,如果目标对象在栈上,新建的对象地址,肯定小于目标对象的地址。因此,新建对象的地址小于目标对象的地址,说明目标对象在栈上,否则在堆上。这里有个小问题,目标对象也可能在静态存储区。另外,这种做法不具有移植性,有些系统的内存布局不是上面的情况。

8、判断对象是否在堆上,很难办。思考下,我们为什么要判断对象是否在堆上?真实的需求是,判断执行delete是否安全。那怎么办呢?

  对于分配获取的指针,放到一个集合,delete指针的时候,判断指针是否在集合,如果在集合,执行delete就是安全的,否则不安全。

9、如何禁止对象产生于heap之中?

  这个很简单,在堆上创建对象,必定调用operator new分配内存,因此将operator new声明为private就好了。

【M27】要求或者禁止对象产生于heap之中的更多相关文章

  1. MoreEffectiveC++Item35 条款27: 要求或禁止对象产生于heap中

    一 要求对象产生在heap中 阻止对象产生产生在non-heap中最简单的方法是将其构造或析构函数声明在private下,用一个public的函数去调用起构造和析构函数 class UPNumber ...

  2. 《MORE EFFECTIVE C++》条款27 要求或者禁止对象分配在堆上

    1. 要求对象分配在堆上 临时对象一般是存在于栈中的,或者是静态对象存在于常量存储区的.那么当创建一个这样的对象的时候,一般是需要隐式或显式地调用构造函数,在销毁的时候调用析构函数的.可以从这方面入手 ...

  3. C++如何禁止对象的复制操作

    最容易想到的是将拷贝构造函数与赋值函数声明为private.但是,private只是说外部不能直接调用,但是可以间接通过类的成员函数与友元函数对其访问.那么怎么办呢? ---->在类中,允许声明 ...

  4. 将一个对象push到数组之中的几点问题

    在项目开发中我们需要向意数组中添加对象:首先想到的是利用数组的api,----push demo: var ar = [1,2,3] var ar2 = [11,22,33] var obj = { ...

  5. C++学习书籍推荐《More Effective C++》下载

    百度云及其他网盘下载地址:点我 编辑推荐 <More Effective C++:35个改善编程与设计的有效方法(中文版)>:传世经典书丛 媒体推荐 <Effective c++&g ...

  6. More Effective C++: 05技术(25-28)

    25:将constructor 和 non-member functions 虚化 所谓 virtual constructor是某种函数,视其输入可产生不同类型的对象.比如下面的代码: class ...

  7. More Effective C++ 35 条款

    一.基础议题(basics) 条款1:仔细区别 pointers 和 references(Distinguish between pointers and references) 一个基本的语法问题 ...

  8. C++ new(2)

    1. new与operator new C++中有很多语法让人难以理解,如:new operator(操作符,下同)和operator new之间差异,确切的说,应该是new与operator new ...

  9. More Effective C++笔记(一)(精心整理)

    一.基础议题 条款1:仔细区别pointers和references 指针使用*和->,引用使用"." 引用必须指向一个已初始化的对象,不能为null,而指针可以指向某个对象 ...

随机推荐

  1. Delphi RxRichEdit高级操作

    unit InsertRichEditUnit;interfaceuses  Windows, Messages, SysUtils, Classes, Graphics, Controls, For ...

  2. duilib List控件,横向滚动时列表项不移动或者显示错位的bug的修复

    转载请说明出处,谢谢~~:http://blog.csdn.net/zhuhongshu/article/details/42264673 关于这个bug的修复我之前写过一篇博客,连接为:http:/ ...

  3. 记一个社交APP的开发过程——基础架构选型(转自一位大哥)

    记一个社交APP的开发过程——基础架构选型 目录[-] 基本产品形态 技术选型 最近两周在忙于开发一个社交App,因为之前做过一点儿社交方面的东西,就被拉去做API后端了,一个人头一次完整的去搭这么一 ...

  4. 转】腾讯云CentOS 6.6安装 Nginx

    原博文出自于: http://www.cnblogs.com/xdp-gacl/p/5290155.html 感谢! 一.下载Nginx 从Nginx的官网(http://nginx.org/en/d ...

  5. uber优步提高成单率,轻松拿奖励!

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  6. 【原创】用Pwnage + Redsnow 制作完美越狱固件

    原帖我发表在威锋论坛 现在貌似IOS 7.X系 大行其道,就算不是IOS7.X ,很多人也装着IOS 6.X系. 进入正文前首先介绍一下自己目前的"环境" 设备:iphone4 G ...

  7. Python下调用Linux的Shell命令

    有时候难免需要直接调用Shell命令来完成一些比较简单的操作,比如mount一个文件系统之类的.那么我们使用Python如何调用Linux的Shell命令?下面来介绍几种常用的方法: 1. os 模块 ...

  8. class tuple

    class tuple(object): """ tuple() -> empty tuple tuple(iterable) -> tuple initia ...

  9. 使用MSSQL,连接oracle,对oracle数据进行操作

    EXEC sp_addlinkedserver--创建链接服务器.链接服务器让用户可以对 OLE DB 数据源进行分布式异类查询. @server = 'Mktg',--要创建的链接服务器的名称.s ...

  10. ACM之数学题

    数学题,始终记得,第一次被带飞师大校赛以及省赛,毫无例外的在数学题上卡死....因此,现在开始,有意识的保留遇见的数学题...(下列知识点按遇见先后顺序排列: 1欧拉公式 欧拉公式的用处是,找出小于N ...