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. C++ STL编程轻松入门基础

    C++ STL编程轻松入门基础 1 初识STL:解答一些疑问 1.1 一个最关心的问题:什么是STL 1.2 追根溯源:STL的历史 1.3 千丝万缕的联系 1.4 STL的不同实现版本 2 牛刀小试 ...

  2. 转载:50个C/C++源代码网站

    来源:http://www.cnblogs.com/feisky/archive/2010/03/05/1679160.html C/C++是最主要的编程语言.这里列出了50名优秀网站和网页清单,这些 ...

  3. <面试经典题>输入框的功能测试点分析

    (废话几句:这个是网上找来的一份模板,高亮部分为自己修改内容,且此面试题很像当年高考的“必考题”性质,触类旁通吧) 1. 输入框UI是否预计了输入内容长度(尽量完整的显示输入内容): 2. 输入框之前 ...

  4. js获取浏览器高度和宽度值,尽量的考虑了多浏览器。

    js获取浏览器高度和宽度值,尽量的考虑了多浏览器. IE中: document.body.clientWidth ==> BODY对象宽度 document.body.clientHeight ...

  5. 链接服务器"(null)"的 OLE DB 访问接口 "Microsoft.Jet.OLEDB.4.0" 返回了消息 "未指定的错误"。[手稿]

    消息 7302,级别 16,状态 1,第 1 行 无法创建链接服务器 "(null)" 的 OLE DB 访问接口 "Microsoft.JET.OLEDB.4.0&qu ...

  6. 项目管理及自动构建工具Maven

    项目管理及自动构建工具Maven 一.Maven安装.目录结构.cmd命令1.下载安装apache-maven-3.2.3-bin.zip下载:http://maven.apache.org/down ...

  7. XHTML学习进度备忘

    书签:XHTML 高级教程没有看:另外跳过的内容有待跟进 __________________ 学习资源:W3School. _________________ 跳过的内容: 1.“XHTML 简介” ...

  8. EF Code First学习笔记

    EF Code First学习笔记 初识Code First EF Code First 学习笔记:约定配置 Entity Framework 复杂类型 Entity Framework 数据生成选项 ...

  9. Ansible的循环

    Ansible的循环 1.       前言 有可能在一个任务中,可能要做很多事情,例如创建多个用户,安装很多个包等,那么就有可能用到循环. 2.       标准循环 重复的任务可以用下面的方式: ...

  10. UML的类图关系分为: 关联、聚合/组合、依赖、泛化(继承)

    UML的类图关系分为: 关联.聚合/组合.依赖.泛化(继承).而其中关联又分为双向关联.单向关联.自身关联:下面就让我们一起来看看这些关系究竟是什么,以及它们的区别在哪里. 1.关联 双向关联:C1- ...