我们知道,C++中引入了New 这个内置符号,很大方便了指针的使用,程序员不必关注与这块堆上新分配的内存是如何来的,如何初始化的,然后如何转换为我们想要的类型指针的。现在,我们重点来分析下这个NEW内置符号背后的步骤和所调用到的函数。这里面涉及到new operator, operator new, placement new.


转载请注明出处: http://blog.csdn.net/elfprincexu

1. New Operator (__type__ * a = new a();)

C 语言当中,我们在新申请一块内存的时候,通常使用的是malloc, 通常通过malloc(size_t size)来获得一块未初始化的raw memory。然后一般情况下我们会对该部分空间初始化(memset or memcpy)。

C++语言引入了new 操作符,极大地方便了使用,它一下子把C语言中的好几个步骤一下完成了,让我们觉得神奇的是,不必去深究其中的调用。

其实,new operator主要做了以下三个步骤的:

std::string* str = new std::string("memory management");// 例如,我们想申请一个新的string空间,其中空间并被初始化为“memory management”,并且该空间由一个stringlei类型的指针来指向,并把它返回给str。

1. 第一步,调用了 operator new 函数, operator new函数的作用 仅仅 是申请一块未被初始化的内存。

函数申明为:void* operator new (size_t size)

void* memory = operator new (sizeof("memory management"));// 申请足够大小的内存空间

2. 第二部,调用string 构造函数,在该未初始化的空间上初始化,也就是“memory management”

call string::string("memory management") on memory*

3. 第三部,将该指针转换为指定的想要的指针类型

string* str =  static_cast<std::string*> (memory);

总结下来:

(1)通过operator new申请内存

(2)使用placement new调用构造函数(简单类型忽略此步)

(3)返回内存指针

2. operator new (该函数仅仅 申请足够大小的内存,可以被重载)

void * operator new (size_t size);

举个例子来讲:

 1 // operator new example  
 2 #include <iostream>  
 3 #include <new>  
 4 using namespace std;  
 5    
 6 struct myclass {myclass() {cout <<"myclass constructed\n";}};  
 7    
 8 int main () {  
 9    
    int * p1 = new int;  
 // same as:  
 // int * p1 = (int*) operator new (sizeof(int));  
    
    int * p2 = new (nothrow)int;  
 // same as:  
 // int * p2 = (int*) operator new (sizeof(int),nothrow);  
    
    myclass * p3 = (myclass*) operator new (sizeof(myclass));  
 // (!) not the same as:  
 // myclass * p3 = new myclass;  
 // (constructor not called by function call, even for non-POD types)  
    
    new (p3) myclass;   // calls constructor  
 // same as:  
 // operator new (sizeof(myclass),p3)  
    
    return ;  

28 }

重载operator new,

void * operator new (size_t size, string str);// 比如我们添加一个形参string, 用来辅助输出

调用

Base *b = new (“Operator new overload example”) Base;// str 形参放在new 后的挂号里面,

same as :

Base *b = (Base* ) ( operator new (sizeof(Base), "Operator new overload example") );

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
class Base {  
public:  
  Base() { }  
   
  void *operatornew(size_t size, string str ) {  
    cout << "Logging an allocation of " << size << " bytes for new object'" << str << "'" << endl;  
    return malloc( size );  
  }  
   
  int var;  
  double var2;  
};  
   
   

Base* b = new ("Base instance 1") Base;

输出: Logging an allocation of 12 bytes for new object 'Base instance 1'

3. Placement new. void* operator new ( size_t size, void* ptr) ;// ptr 会被返回,因为我们已经指定在已知的内存上

归根结底来讲,placement new 是operator new 的一种特殊重载,它不分配内存,只是调用合适的构造函数在ptr所指的地方构造一个对象,之后返回实参指针ptr。

例如:

myclass* p3 = static_cast<myclass*> ( operator new (sizeof(myclass));// p3 已经指定一块足够放下myclass对象的空间,该空间未初始化,

new (p3) myclass;// placement new, 在指定的p3空间上,call constructor myclass()来初始化该空间,并且返回p3.

1 // operator new example

 2 #include <iostream>  
 3 #include <new>  
 4 using namespace std;  
 5    
 6 struct myclass {myclass() {cout <<"myclass constructed\n";}};  
 7    
 8 int main () {  
 9    myclass * p3 = (myclass*) operator new (sizeof(myclass));  
 // (!) not the same as:  
 // myclass * p3 = new myclass;  
 // (constructor not called by function call, even for non-POD types)  
    
    new (p3) myclass;   // calls constructor  
 // same as:  
 // operator new (sizeof(myclass),p3)  
    
    return ;  
 }  

【转】C++易混知识点3. New Operator, Operator New, Placement New 实例分析,比较区别的更多相关文章

  1. 【转】 C++易混知识点4: 自己编写一个智能指针(Reference Counting)学习auto_ptr和reference counting

    这篇文章建大的介绍了如何编写一个智能指针. 介绍: 什么是智能指针?答案想必大家都知道,智能指针的目的就是更好的管理好内存和动态分配的资源,智能指针是一个智能的指针,顾名思义,他可以帮助我们管理内存. ...

  2. 【转】C++易混知识点1: 指针常量和常量指针的区别,附有详细案例解释

    熟悉C++也已经有一些年头了,今天突然翻出当年浏览的书籍,对一些概念居然生疏了,指针常量和常量指针由于 指针 这一特殊的对象而变得难以区别.因此,在思考再三之后,决定写下该篇总结,加强对他们的区别: ...

  3. 【转】 C++易混知识点2. 函数指针和指针函数的区别

    我们时常在C++开发中用到指针,指针的好处是开销很小,可以很方便的用来实现想要的功能,当然,这里也要涉及到指针的一些基本概念.指针不是基本数据类型,我们可以理解他为一种特殊类型的对象,他占据一定空间, ...

  4. 【转】C++易混知识点5:实例讲解Public Protected Private作用域,继承的区别和用意

    大学生涯,涉及到类的作用域,继承都是用的public 共有继承,当时也没想那么多,觉得共有继承多方便,多简单,反正没有太多的限制,不管是类的成员或者是基类的成员函数都可以访问.没有深究.其实这里面真是 ...

  5. JavaScript易错知识点整理

    前言 本文是我学习JavaScript过程中收集与整理的一些易错知识点,将分别从变量作用域,类型比较,this指向,函数参数,闭包问题及对象拷贝与赋值这6个方面进行由浅入深的介绍和讲解,其中也涉及了一 ...

  6. JavaScript 易错知识点整理

    本文是我学习JavaScript过程中收集与整理的一些易错知识点,将分别从变量作用域,类型比较,this指向,函数参数,闭包问题及对象拷贝与赋值这6个方面进行由浅入深的介绍和讲解,其中也涉及了一些ES ...

  7. SQL Server,Access数据库查询易混点和C#中parameter指定参数长度的优缺点

    在学校的时候就经常做一些网站,所以这次在公司实习,组长第一次给了一个企业的网站还是很快的完成了.中间并没有遇到什么大的问题,但是还是遇到了两个新手非常容易混淆的小问题,所以拿出来跟大家分享一下. 主要 ...

  8. JavaScript易错知识点整理[转]

    前言 本文是我学习JavaScript过程中收集与整理的一些易错知识点,将分别从变量作用域,类型比较,this指向,函数参数,闭包问题及对象拷贝与赋值这6个方面进行由浅入深的介绍和讲解,其中也涉及了一 ...

  9. JS易错知识点

    JAVASCRIPT易错知识点整理 前言 本文是学习JavaScript过程中收集与整理的一些易错知识点,将分别从变量作用域,类型比较,this指向,函数参数,闭包问题及对象拷贝与赋值这6个方面进行由 ...

随机推荐

  1. js 移动端上拉加载下一页通用方案

    取页面三种高度 //取进度条到底部距离 var getScrollTop = function () { var scrollTop = 0; if (document.documentElement ...

  2. WPF 依赖属性源码 洞察微软如何实现DependencyProperty

    依赖属性DependencyProperty是wpf最重要的一个类,理解该类如何实现对学习wpf帮助很大! 终于找到了该类的源码!仔细阅读源码,看看微软如何玩的花招! File: Base\Syste ...

  3. GNS3的配置

    为了更好的了解协议我决定学习CCNA 安装好GNS3后我们打开 点击设置 先把iso解压,解压完成后倒入 保存结束 然后在输入idlepc get 设备名称 来计算idepc的值 idepc能让我们p ...

  4. 如何上传webshell后改回原来的webshell的格式

    一般后台不给允许上传php,asp格式的东东 所以我们要把木马改为jpg格式 记录下上传的路径 我们上传后木马因为格式不对不能被正确解析,我们可以利用网站的备份数据库模式恢复格式 在备份数据库那填上我 ...

  5. cs231n spring 2017 lecture14 Reinforcement Learning 听课笔记

    (没太听明白,下次重新听) 1. 增强学习 有一个 Agent 和 Environment 交互.在 t 时刻,Agent 获知状态是 st,做出动作是 at:Environment 一方面给出 Re ...

  6. Redux 介绍

    本文主要是对 Redux 官方文档 的梳理以及自身对 Redux 的理解. 单页面应用的痛点 对于复杂的单页面应用,状态(state)管理非常重要.state 可能包括:服务端的响应数据.本地对响应数 ...

  7. 洛谷 P1028 数的计算【递推】

    P1028 数的计算 题目描述 我们要求找出具有下列性质数的个数(包含输入的自然数n): 先输入一个自然数n(n<=1000),然后对此自然数按照如下方法进行处理: 1.不作任何处理; 2.在它 ...

  8. 2017 Multi-University Training Contest - Team 1 1003&&HDU 6035 Colorful Tree【树形dp】

    Colorful Tree Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)T ...

  9. maven学习3,如何创建一个web项目

      Maven学习 (三) 使用m2eclipse创建web项目   1.首先确认你的eclipse已经安装好m2eclipse的环境,可以参照上两篇Maven学习内容 2.新建一个maven的项目 ...

  10. WPF 简单的循环GIF播放

    //MVVM要事件绑定,记得项目引用类库“Sysrem.Windows.interactivity”,然后XAML引用 xmlns:i="http://schemas.microsoft.c ...