禁止或强制使用堆分配---《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 目录 不定期更新中-- 基础知识 数据计量单位 面向对象三大特性 基础数据类型 注释格式 访问修饰符 运算符 算数运算符 关系运算符 位运算符 逻辑运算符 赋值运算符 三目表达式 ...
 
随机推荐
- [转]ASP.NET MVC 5 - 创建连接字符串(Connection String)并使用SQL Server LocalDB
			
您创建的MovieDBContext类负责处理连接到数据库,并将Movie对象映射到数据库记录的任务中.你可能会问一个问题,如何指定它将连接到数据库? 实际上,确实没有指定要使用的数据库,Entity ...
 - ios开发之 -- 自动轮播图创建
			
这里是oc版本的,简单记录下: 具体代码如下: 1,准备 #define FRAME [[UIScreen mainScreen] bounds] #define WIDTH FRAME.size.w ...
 - ios开发 int,NSInteger,NSUInteger,NSNumber
			
分享一下,在工作工程中遇到的一些不留心的地方: 1.当需要使用int类型的变量的时候,可以像写C的程序一样,用int,也可以用NSInteger,但更推荐使用NSInteger,因为这样就不用考虑设备 ...
 - 【RF库Collections测试】Get Index From List
			
Name:Get Index From ListSource:Collections <test library>Arguments:[ list_ | value | start=0 | ...
 - js中字符串支持正则表达式的方法
			
设一个字符串var myName = "fangming";则支持正则表达式的方法有:split(分割),replace(替换),search(查找),match(元素参数的数组) ...
 - Android 使用CheckBox实现多选效果
			
CheckBox:复选框1.有两种状态: 选中状态(true),未选中状态(false)2.属性: android:id="@+id/checkbox" android:layou ...
 - 关于Activity的getReferrer():如何在Activity中获取调用者?
			
http://blog.csdn.net/u013553529/article/details/53856800 关于Activity的getReferrer()之一:如何在Activity中获取调用 ...
 - executeQuery、executeUpdate 和 execute
			
Statement 接口提供了三种执行 SQL 语句的方法:executeQuery.executeUpdate 和 execute.使用哪一个方法由 SQL 语句所产生的内容决定. 1. Resul ...
 - 【BZOJ1915】[Usaco2010 Open]奶牛的跳格子游戏 DP+单调队列
			
[BZOJ1915][Usaco2010 Open]奶牛的跳格子游戏 Description 奶牛们正在回味童年,玩一个类似跳格子的游戏,在这个游戏里,奶牛们在草地上画了一行N个格子,(3 <= ...
 - jvm原理之内存机制
			
转自:https://www.cnblogs.com/dreamowneryong/p/6381633.html JVM栈由堆.方法区,栈.本地方法栈.程序计数器等部分组成,结构图如下所示: 还有一张 ...