有时候,指明一些特定类的对象不应该被分配到堆(heap)上是个好主意。通常这是为了确保该对象的析构函数一定会得到调用。维护对象本身(body object)的引用计数的句柄对象(handle object)就属于这种对象。具有自动存储区的类的局部对象,其析构函数会被自动调用(exit 或abort发生的非正常的程序终止情况出外),具有静态存储区的对象依然(abort除外),而堆分配的对象则必须被显示的销毁。

指明对象不应该被分配到堆上的方式之一,是将其内存分配定义为不合法:

#include<iostream>
class NoHeap{
protected:
    void * operator new(size_t){return 0;}
    //size_t 参数将被自动初始化为NoHeap对象的大小(以字节为单位)。
    void  operator delete(void *){}
    //void * 参数被编译器自动设置为"将被delete的那个对象地址"
private:
    void * operator new[](size_t){return 0;}
    void operator delete[](void *);
};
class OnHeap{
private:
    ~OnHeap(){};
public:
    void destory(){ delete this;}
    //同时要提供一个共有的销毁对象的方法(例如:destroy),否则创建的对象将无从销毁
}; int main(int argc, char* argv[])
{
     NoHeap ok;     NoHeap * nh = new NoHeap;//错误!
    delete nh;//错误!
    
    OnHeap oh1; //错误!隐式调用私有析构函数     OnHeap *oh2 = new OnHeap; //正确!
    oh2->destory(); //正确!
    return 0;
}

任何在堆上分配一个NoHeap对象的习惯性尝试,都将会导致编译期错误。

之所以给出operator new 和 operator delete的定义(和声明),是因为在一些平台上他们可能会被构造函数和析构函数隐式调用。出于同样原因,我们将其声明为protected,因为它们可能会被派生类的构造函数和析构函数隐式调用。如果NoHeap不做基类,那么这两个函数也可以声明为private的。

同时,还要注意阻止在堆上分配NoHeap对象的数组。在这种情况下,只要将 array new 和 array delete声明为private且不予以定义即可,类似于禁止复制操作的方式。

当然,在某些场合下,我们可能鼓励而非阻止使用堆分配,为此,只需将析构函数声明为private即可。当对象的名字离开作用域时,任何一个声明或静态OnHeap对象的尝试,都将会导致一个隐式析构函数的调用,将发生错误。

禁止或强制使用堆分配---《C++必知必会》 条款34的更多相关文章

  1. 《C++必知必会》学习笔记

    转载:http://dsqiu.iteye.com/blog/1734640 条款一 数据抽象 抽象数据设计遵循步骤:(1)为类型取一个描述性的名字.(2)列出类型所能执行的操作,不要忘了初始化(构造 ...

  2. SQL 必知必会

    本文介绍基本的 SQL 语句,包括查询.过滤.排序.分组.联结.视图.插入数据.创建操纵表等.入门系列,不足颇多,望诸君指点. 注意本文某些例子只能在特定的DBMS中实现(有的已标明,有的未标明),不 ...

  3. 《MySQL必知必会》整理

    目录 第1章 了解数据库 1.1 数据库基础 1.1.1 什么是数据库 1.1.2 表 1.1.3 列和数据类型 1.1.4 行 1.1.5 主键 1.2 什么是SQL 第2章 MySQL简介 2.1 ...

  4. 读《MySQL必知必会》我学到了什么?

    前言 最近在写项目的时候发现自己的SQL基本功有些薄弱,遂上知乎查询MYSQL关键字,期望得到某些高赞答案的指点,于是乎发现了 https://www.zhihu.com/question/34840 ...

  5. 【MySQL 基础】MySQL必知必会

    MySQL必知必会 简介 <MySQL必知必会>的学习笔记和总结. 书籍链接 了解SQL 数据库基础 什么是数据库 数据库(database):保存有组织的数据的容器(通常是一个文 件或一 ...

  6. 脑残式网络编程入门(三):HTTP协议必知必会的一些知识

    本文原作者:“竹千代”,原文由“玉刚说”写作平台提供写作赞助,原文版权归“玉刚说”微信公众号所有,即时通讯网收录时有改动. 1.前言 无论是即时通讯应用还是传统的信息系统,Http协议都是我们最常打交 ...

  7. 第5节:Java基础 - 必知必会(下)

    第5节:Java基础 - 必知必会(下) 本小节是Java基础篇章的第三小节,主要讲述Java中的Exception与Error,JIT编译器以及值传递与引用传递的知识点. 一.Java中的Excep ...

  8. MySQL必知必会1-20章读书笔记

    MySQL备忘 目录 目录 使用MySQL 检索数据 排序检索数据 过滤数据 数据过滤 用通配符进行过滤 用正则表达式进行搜索 创建计算字段 使用数据处理函数 数值处理函数 汇总数据 分组数据 使用子 ...

  9. 必知必会之 Java

    必知必会之 Java 目录 不定期更新中-- 基础知识 数据计量单位 面向对象三大特性 基础数据类型 注释格式 访问修饰符 运算符 算数运算符 关系运算符 位运算符 逻辑运算符 赋值运算符 三目表达式 ...

随机推荐

  1. vertica时间计算SQL语句实例:统计一天内登录的用户

    SQL语句实例: select count(id) as num from public.user where cast((CURRENT_TIMESTAMP-login_timed) day as ...

  2. CCNet持续集成编译中SVN问题解决

    SVN问题 BUILD EXCEPTION Error Message: ThoughtWorks.CruiseControl.Core.CruiseControlException: Source ...

  3. list的下标【python】

    转自:http://www.cnblogs.com/dyllove98/archive/2013/07/20/3202785.html list的下表从零开始,和C语言挺类似的,但是增加了负下标的使用 ...

  4. Spring new对象时注解失效

    新建了一个新类(A)后,在类中用注解将属性注入.类名(A)上用 @Component ,类中的一个属性(name)上用 @Autowired或@Resource, 方法(fun)中通过 属性(name ...

  5. 通过Nagios监控weblogic服务

    1.前言      前段时间搭建了一套Nagios监控服务,心血来潮想自己写一个脚本,拓展Nagios插件来监控公司的weblogic服务. 环境:weblogic10.3.3.0 . CentOS6 ...

  6. ARM承认芯片漏洞:披露修复细节

    在谷歌安全研究人员曝光了影响整个芯片产业的CPU设计漏洞后,ARM的Cortex系列处理器也未能逃过一劫.在一篇致开发者的博客文章中,该公司披露了三个已知漏洞的细节——其中两个与Spectre有关.第 ...

  7. 《C++ Primer Plus》第7章 函数——C++的编程模块 学习笔记

    函数是C++的编程模块.要使用函数,必须提供定义和原型,并调用该函数.函数定义是实现函数功能的代码:函数原型描述了函数的接口:传递给函数的值的书目和种类以及函数的返回类型.函数调用使得程序将参数传递给 ...

  8. swiper的延迟加载(非官网方法)

    网上找的: https://github.com/nolimits4web/Swiper/issues/626 var tabsSwiper = new Swiper('#games-content' ...

  9. chrom调试

    2.Event Listeners 可以看到事件找到对应在标签点开里有useCapture, passive: once: handler等等右键handler 的"show functio ...

  10. 【BZOJ2938】[Poi2000]病毒 AC自动机+DFS

    [BZOJ2938][Poi2000]病毒 Description 二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码.如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码 ...