禁止或强制使用堆分配---《C++必知必会》 条款34
有时候,指明一些特定类的对象不应该被分配到堆(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的更多相关文章
- 《C++必知必会》学习笔记
转载:http://dsqiu.iteye.com/blog/1734640 条款一 数据抽象 抽象数据设计遵循步骤:(1)为类型取一个描述性的名字.(2)列出类型所能执行的操作,不要忘了初始化(构造 ...
- SQL 必知必会
本文介绍基本的 SQL 语句,包括查询.过滤.排序.分组.联结.视图.插入数据.创建操纵表等.入门系列,不足颇多,望诸君指点. 注意本文某些例子只能在特定的DBMS中实现(有的已标明,有的未标明),不 ...
- 《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 ...
- 读《MySQL必知必会》我学到了什么?
前言 最近在写项目的时候发现自己的SQL基本功有些薄弱,遂上知乎查询MYSQL关键字,期望得到某些高赞答案的指点,于是乎发现了 https://www.zhihu.com/question/34840 ...
- 【MySQL 基础】MySQL必知必会
MySQL必知必会 简介 <MySQL必知必会>的学习笔记和总结. 书籍链接 了解SQL 数据库基础 什么是数据库 数据库(database):保存有组织的数据的容器(通常是一个文 件或一 ...
- 脑残式网络编程入门(三):HTTP协议必知必会的一些知识
本文原作者:“竹千代”,原文由“玉刚说”写作平台提供写作赞助,原文版权归“玉刚说”微信公众号所有,即时通讯网收录时有改动. 1.前言 无论是即时通讯应用还是传统的信息系统,Http协议都是我们最常打交 ...
- 第5节:Java基础 - 必知必会(下)
第5节:Java基础 - 必知必会(下) 本小节是Java基础篇章的第三小节,主要讲述Java中的Exception与Error,JIT编译器以及值传递与引用传递的知识点. 一.Java中的Excep ...
- MySQL必知必会1-20章读书笔记
MySQL备忘 目录 目录 使用MySQL 检索数据 排序检索数据 过滤数据 数据过滤 用通配符进行过滤 用正则表达式进行搜索 创建计算字段 使用数据处理函数 数值处理函数 汇总数据 分组数据 使用子 ...
- 必知必会之 Java
必知必会之 Java 目录 不定期更新中-- 基础知识 数据计量单位 面向对象三大特性 基础数据类型 注释格式 访问修饰符 运算符 算数运算符 关系运算符 位运算符 逻辑运算符 赋值运算符 三目表达式 ...
随机推荐
- CUGBACM Codeforces Tranning 1 题解
链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=61581#overview 描写叙述:非常老的CF题,题不错,拿来训练正好. 做的时 ...
- 一、SDWebImage分析--库处理流程分析
二.SDWebImage分析--源码具体分析 这阵子看了SDWebImage的实现跟源代码.也看了下网上的一些总结. 这里我自己画了个流程图来辅助理解下SDWebImage这个库的实现流程.相信也是有 ...
- ios - UILabel全属性
label是大家在开发过程中使用频率很高的一个用来显示文本信息的控件,但是她所有的属性你都了解吗,下面让我们来 重新认识一下label! 1.创建 CGRect rect = CGRectMake(, ...
- Access数据操作-02
数据库连接 MDB文件 :Provider=Microsoft.Jet.OLEDB.4.0;Data Source=*.mdb ;Persist Security Info=False; AccDB文 ...
- url重写(urlrewrite)的一些系统变量
学php也有3年了,一直对url重写不是很了解,本学用到的话都是百度一下,再复制作简单修改,一些变量的参数都不太了解什么意思,难得今天有时间,做个笔记吧! 1)可用的一些系统变量,在重写条件和重写规则 ...
- JS 添加js节点
function AddScriptNode(src) { var N = document.createElement("script"); N.setAttribute(&qu ...
- 解决 ssh 登录到ubuntu server 慢的问题
最近在服务器上使用ubuntu系统,服务器上开启sshd服务,在客户端处使用ssh登录到服务器的时候出现卡顿的现象. 在网上搜索了解决方案,主要是: 1. 修改服务器的 /etc/ssh/sshd_c ...
- Android 7.1 SystemUI--任务管理--场景一:长按某个缩略图,拖动分屏的流程
TaskView 类的长按事件 onLongClick 方法内发送了 DragStartEvent 事件消息,该 DragStartEvent 事件消息由 RecentsView,TaskStackV ...
- 使用commons-email解析 eml文件
在对eml文件进行索引的时候需要先对其进行解析,提取出其中的收件人.发件人.文件内容和附件等信息 下边是解析eml文件的一个demo(在运行之前需要先导入mail.jar 和commons-email ...
- 【BZOJ1054】[HAOI2008]移动玩具 BFS
[BZOJ1054][HAOI2008]移动玩具 Description 在一个4*4的方框内摆放了若干个相同的玩具,某人想将这些玩具重新摆放成为他心中理想的状态,规定移动 时只能将玩具向上下左右四个 ...