有时候,指明一些特定类的对象不应该被分配到堆(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. mybatis由浅入深day01_1课程安排_2对原生态jdbc程序中问题总结

    mybatis 第一天 mybatis的基础知识 1 课程安排: mybatis和springmvc通过订单商品 案例驱动 第一天:基础知识(重点,内容量多) 对原生态jdbc程序(单独使用jdbc开 ...

  2. 说说M451的例程库的说明

    Directory Information Document   Driver reference manual and reversion history. Library         Driv ...

  3. 浅谈 SSD,eMMC,UFS(转自知乎)

    但作为一个计算机体系结构的研究生,在这些名词满天飞的时候,我的好奇心是抑制不住的,想一探这几样技术的究竟.本文不对某一特定事件进行点评,仅从技术角度分析对比一下这三种技术.就算是当做自己的技术储备+科 ...

  4. easyui —— footer

    前言: 使用easyui的datagrid,在最后一行加上“总计”字样,效果如下: 过程: ... <table id="dg" title="xx管理" ...

  5. KVC与Runtime结合使用(案例)及其底层原理

    一.KVC 的用法和实践 用法 KVC(Key-value coding)键值编码,顾名思义.额,简单来说,是可以通过对象属性名称(Key)直接给属性值(value)编码(coding)“编码”可以理 ...

  6. mysql 数据表读锁机制详解

    为了给高并发情况下的mysql进行更好的优化,有必要了解一下mysql查询更新时的锁表机制.一.概述MySQL有三种锁的级别:页级.表级.行级.MyISAM和MEMORY存储引擎采用的是表级锁(tab ...

  7. 【linux】Centos下登陆mysql报错#1045 - Access denied for user 'root'@'localhost' (using password: NO)

    创建mysql  远程链接 grant all privileges on *.* to 'test'@"%" identified by "test666 with g ...

  8. ajax jquery校验用户是否已经注册

    服务端代码这里就不贴了 html代码比较简单,需要自行引入jquery库 <body> 请输入用户名:<input type="text" id="us ...

  9. 关于js的面向对象设计

    function Person( name, age ){ this.name = name; this.age = age; this.sleep = function(){ alert( this ...

  10. JavaBean入门及简单的例子

    不会编写JavaBean就不是一个Java开发人员. 那么,何谓JavaBean呢? JavaBean是符合某种规范的Java组件,也就是Java类. 它必须满足如下规范: 1)必须有一个零参数的默认 ...