深入理解c++中的new与delete

一,new与delete的细节

假如有下面的代码:

string *sp = new string("a value");
string *arr = new string[10];

整个new的语句可以分为三步完成,

首先,编译器使用名为operator new(operator new[])的标准库函数,该函数的作用是分配一块足够大的、原始的空间。第二步,编译器运行相应的构造函数构造对象,第三步,编译器将得到的对象首地址返回。

当在程序中使用 type *p = new type(..)时,编译器按照两条原则寻找对应的operator:

  如果Type是用户自定义类型,优先在类以及父类的成员函数中寻找operator new函数,如果没有,则在全局函数中寻找用户的自定义版本,再没有则使用标准库的版本

  如通用户定义了和标准库一样的函数,不会报重定义

标准库定义了八个可供用户重载在版本,其中nothrow_t定义在头文件new中,用于表示不抛出异常

void *operator new (size_t);
void *operator new[] (size_t);
void operator delete (void *) noexcept;
void operator delete[] (void *) noexcept;

void *operator new (size_t, std::nothrow_t) noexcept;
void *operator new[] (size_t, std::nothrow_t) noexcept;
void operator delete(void*, std::nothrow_t) noexcept;
void operator delete[](void *, std::nothrow_t) noexcept;

用户可以自定义上面的几个函数(注意是自定义,不是重载,参数类型、个数只要满足要求即可,即使与标准库定义的一样也不会报错),这些要求包括:

1, 不能定义这样的new :void *operator new(size_t. void *), 他只能被标准库使用

2,new必须返回void*, 第一个参数必须是size_t,且不能有默认参数

3,delete必须返回void, 第一个参数必须是void *

4,当我们在类中定义operator delete时,若将第二个参数置为size_t, 那该形参的初始值就会变成第一个形参所指物的大小,如果这个类有一个虚析构函数,那么size_t的大小和operator delete的版本将有具体的动态类型决定,虽然我也不太懂,暂且先记下来- -!

二、定位new(placement new)

上面提到的operator new()函数会分配空间,虽然我们可以显式调用对象的析构函数,但是却没有办法调用对象的构造函数,此时需要用到一个叫做定位new的函数,该函数只接受一个void *参数,之后会在该指针所指的位置,调用构造函数,构造出一个对象。具体的各种形式如下:

new (place_addr) type;

new (place_addr) type (initilizers);

new(place_addr) type [size];

new(place_addr) type[size] (initilizers);

值得注意的是,定位new并不规定这个构造对象的空间是什么空间,可以是标准库的operator new出来的,可以是用户自己的operator new出来的,可以是malloc出来的,甚至可以是栈中的自动变量,如数组- -!,随便是啥都可以。

三、总结

虽然这些东西平时不常用,但是在需要自己精确控制对象的空间分配以及初始化行为时,仅仅从析构函数与构造函数是不够的,这些技术在STL中的内存分配器中就被广泛使用。

时间: 2024-12-29 23:38:38

深入理解c++中的new与delete的相关文章

深入理解javascript 中的 delete(转)

在这篇文章中作者从<JavaScript面向对象编程指南>一书中关于 delete 的错误讲起,详细讲述了关于 delete 操作的实现, 局限以及在不同浏览器和插件(这里指 firebug)中的表现. 下面翻译其中的主要部分. ...书中声称 “函数就像一个普通的变量那样——可以拷贝到不同变量,甚至被删除” 并附上了下面的代码片段作为说明: >>> var sum = function(a, b) {return a+b;}; >>> var add =

深入理解JavaScript中创建对象模式的演变(原型)

创建对象的模式多种多样,但是各种模式又有怎样的利弊呢?有没有一种最为完美的模式呢?下面我将就以下几个方面来分析创建对象的几种模式: Object构造函数和对象字面量方法 工厂模式 自定义构造函数模式 原型模式 组合使用自定义构造函数模式和原型模式 动态原型模式.寄生构造函数模式.稳妥构造函数模式 第一部分:Object构造函数和对象字面量方法 我之前在博文<javascript中对象字面量的理解>中讲到过这两种方法,如何大家不熟悉,可以点进去看一看回顾一下.它们的优点是用来创建单个的对象非常方

深入理解JavaScript中的属性和特性

深入理解JavaScript中的属性和特性? JavaScript中属性和特性是完全不同的两个概念,这里我将根据自己所学,来深入理解JavaScript中的属性和特性. 主要内容如下: 理解JavaScript中理解对象的本质.理解对象与类的关系.对象与引用类型的关系 对象属性如何进行分类 属性中特性的理解 第一部分:理解JavaScript中理解对象的本质.理解对象与类的关系.对象与引用类型的关系 对象的本质:ECMA-262把对象定义为:无序属性的集合,其属性可以包含基本值.对象或者函数.即

理解javascript中的原型模式

一.为什么要用原型模式. 早期采用工厂模式或构造函数模式的缺点:  1.工厂模式:函数creatPerson根据接受的参数来构建一个包含所有必要信息的person对象,这个函数可以被无数次的调用,工厂模式尽管解决了创建多个相似对象的问题,却没有解决对象识别的问题(返回的是自定义的一个对象o,不明确对象o的类型).  2. 构造函数模式:构造函数的调用和其他oo语言一样,用new操作符来构建一个Person的实例:javascript中的构造函数也是函数(所以也可以直接像普通函数那样直接调用方法名

深入理解Java中的IO

深入理解Java中的IO 引言:     对程序语言的设计者来说,创建一个好的输入/输出(I/O)系统是一项艰难的任务 < Thinking in Java >   本文的目录视图如下: Java IO概要 a.Java IO中常用的类 b.Java流类的类结构图 1.流的概念和作用 2.Java IO所采用的模型  : 3.IO流的分类 4.Java IO流对象 1.输入字节流InputStream 2.输出字节流OutputStream 3.字符输入流Reader 4.字符输出流Write

如何理解T-SQL中Merge语句(二)

写在前面的话:上一篇写了如何理解T-SQL中Merge语句,基本把Merge语句要讲的给讲了,在文章的后面,抛出了几个结,当时没有想明白怎么去用文字表达,这一篇就来解答一下这几个结,又是一篇“天马行空”的文字,大家凑合看吧. ===正文开始=== 先看下面表一(Student_Target)和表二(Student_Source). 一.When Matched部分 执行下面SQL语句: MERGE INTO Student_Target AS st USING Student_Source AS

深入理解c++中char*与wchar_t*与string以及wstring之间的相互转换 [转]

本篇文章是对c++中的char*与wchar_t*与string以及wstring之间的相互转换进行了详细的分析介绍,需要的朋友参考下. 1 #ifndef USE_H_ 2 #define USE_H_ 3 4 #include <iostream> 5 #include <windows.h> 6 #include <string> 7 using namespace std; 8 class CUser 9 { 10 public: 11 CUser(); 12

理解RabbitMQ中的AMQP-0-9-1模型

前提 之前有个打算在学习RabbitMQ之前,把AMQP详细阅读一次,挑出里面的重点内容.后来找了下RabbitMQ的官方文档,发现了有一篇文档专门介绍了RabbitMQ中实现的AMQP模型部分,于是直接基于此文档和个人理解写下这篇文章. AMQP协议 AMQP全称是Advanced Message Queuing Protocol,它是一个(分布式)消息传递协议,使用和符合此协议的客户端能够基于使用和符合此协议的消息传递中间件代理(Broker,也就是经纪人,个人感觉叫代理合口一些)进行通信.

深入理解CSS中的层叠上下文和层叠顺序(转)

by zhangxinxu from http://www.zhangxinxu.com 本文地址:http://www.zhangxinxu.com/wordpress/?p=5115 零.世间的道理都是想通的 在这个世界上,凡事都有个先后顺序,凡物都有个论资排辈.比方说食堂排队打饭,对吧,讲求先到先得,总不可能一拥而上.再比如说话语权,老婆的话永远是对的,领导的话永远是对的. 在CSS届,也是如此.只是,一般情况下,大家歌舞升平,看不出什么差异,即所谓的众生平等.但是,当发生冲突发生纠葛的时