new operator  new操作符

operator new  操作符new

placement new  定位new

string *ps = new string("Memory Management"); 

这里的new是new 操作符。这里共有两个步骤的工作要做:

①为对象申请空间 ②调用构造函数初始化内存中的对象

new 操作符总是做这两件事,不可以任何方式改变其行为。

但是你可以改变步骤①如何为对象申请空间。

new 操作符是通过 operator new这个函数为对象申请空间。

operator new 的声明形式

void* operator new(size_t size);//在做其他形式重载时也要保证第一个参数必须为size_t类型

函数的返回值是 void*,参数size确定分配多少内存

该函数调用时与普通函数一样

ST *pt = operator new(sizeof(ST));

placement new的作用是在已经被分配但是尚未处理的(raw)内存中构造一个对象。它是一个特殊的operator new

void* operator new(size_t, void *p)//参数size_t没有名字,但是为了防止编译器警告必须加上
{
return p;
}

在使用placement new时调用者已经获得了指向内存的指针,因为调用者知道对象应该放在

哪里。placement new必须做的就是返回传递给它的指针。

总结:如果你想在堆上建立一个对象,应该使用new 操作符,它既分配内存又为对象调用构造函数;

   如果你只想分配内存,就调用operator new函数,它不会调用构造函数;

    如果你想定制自己的在堆对象被建立时的内存分配过程,你应该写自己的operator new 函数,然后使用

new操作符,new操作符会调用你定制的operator new。

   如果你想在一块已经获得指针的内存里建立一个对象,应该使用palcement new.

#include<iostream>
#include<vld.h>
using namespace std;
class ST
{
private:
char *ptr;
public:
ST(const char *str = ""):ptr("")
{
cout<<"Object was built. "<<endl;
if(str == NULL)
{
this->ptr = new char[1];
this->ptr[0] = '\0';
}
else
{
this->ptr = new char [strlen(str)+1];
strcpy(ptr, str);
}
}
~ST()
{
cout<<"Object was free. "<<endl;
delete []this->ptr;
ptr = NULL;
}
void* operator new(size_t, void *p)//placement new
{
return p;
}
void operator delete(void *p)
{
cout<<"---"<<endl;
free(p);
}
};
void* operator new(size_t t)
{
void *p = malloc(t);
return p;
}void* operator new[](size_t t)
{
void *p = malloc(t);
return p;
}
void operator delete[](void *p)
{
cout<<"--[][]\n";
free(p);
return;
}
void main()
{
ST *pt = (ST*)operator new (sizeof(ST)); //使用重载的operator new 为对象pt分配空间
new(pt)ST("Hello");      //这里调用placement new,同时也调用了构造函数。前两行代码等价于在未重载new时 ST *pt = new ST("Hello");
pt->~ST();           //通过pt指针可直接调用析构函数,但是不可调用构造函数
operator delete (pt);    //调用operator delete函数 后行代码等价于在未重载delete时 delete pt

运行结果

为了避免内存泄漏,每个动态内存分配必须与一个等同相反的deallocation对应。

函数operator delete与delete操作符的关系和operator new与new操作符一样。

注意,在使用placement new在内存建立对象时,应避免使用delete操作符。

应该显式调用对象的析构函数来解除构造函数的影响。

在为对象数组申请空间时必可重载 operator new[] 函数而不再使用operator new函数。

例如

ST *pt = new ST[3];

这个过程共调用3次构造函数

将上例主函数修改为

void main()
{
ST *pr = new ST[3];
delete[] pr;//[]一定不可缺少
}

运行结果为

理解各种不同含义的 new 和 delete的更多相关文章

  1. 阅读《Effective C++》系列

    <Effective C++>条款07:为多态基类声明virtual析构函数 这样做主要是为了防止内存泄漏,见我hexo博客. C++的虚析构函数 <Effective C++> ...

  2. More Effective C++ (1)

    简单分析总结了more effective c++ 的前十个条款: 剩下的条款to be continue~ 1.仔细区分指针和引用引用必须不能指向空,指针可以指向空,指针初始化是记得赋空值,重载某些 ...

  3. MySQL外键约束On Delete、On Update各取值的含义

    主键.外键和索引的区别?   主键 外键 索引 定义: 唯一标识一条记录,不能有重复的,不允许为空 表的外键是另一表的主键, 外键可以有重复的, 可以是空值 主索引(由关键字PRIMARY定义的索引) ...

  4. C/C++学习笔记----指针的理解

    指针是C/C++编程中的重要概念之一,也是最容易产生困惑并导致程序出错的问题之一.利用指针编程可以表示各种数据结构,通过指针可使用主调函数和被调函数之间共享变量或数据结构,便于实现双向数据通讯:指针能 ...

  5. 转:如何学习SQL(第二部分:从关系角度理解SQL)

    转自:http://blog.163.com/mig3719@126/blog/static/285720652010950825538/ 6. 从关系角度理解SQL 6.1. 关系和表 众所周知,我 ...

  6. C++指针理解

    指针是C/C++编程中的重要概念之一,也是最容易产生困惑并导致程序出错的问题之一.利用指针编程可以表示各种数据结构,通过指针可使用主调函数和被调函数之间共享变量或数据结构,便于实现双向数据通讯:指针能 ...

  7. 深入理解JavaScript系列(12):变量对象(Variable Object)

    介绍 JavaScript编程的时候总避免不了声明函数和变量,以成功构建我们的系统,但是解释器是如何并且在什么地方去查找这些函数和变量呢?我们引用这些对象的时候究竟发生了什么? 原始发布:Dmitry ...

  8. Hadoop的理解笔记

    1.2Hadoop与云计算的关系1.什么是云计算:一种基于互联网的计算,在其中共享的资源.软件和信息以一种按需的方式提供给计算机和设备 , 就如同日常生活中的电网一样. 什么是Hadoop:Hadoo ...

  9. 20155315庄艺霖--对做中学的理解及对c语言和Java的看法

    关于做中学的理解及技能训练的思考 在写这篇博客之前,我首先阅读了娄老师的博客,对做中学的概念很感兴趣.我们常说知识要学以致用,做中学强调的是在用的过程中有新的收获和体会来进一步巩固学习.细数我学过的课 ...

随机推荐

  1. hdu 5100 Chessboard (额,,,,,就叫它趣味数学题吧)

    题意: 用K*1的砖块去覆盖N*N的大矩形,问最多能覆盖多少块. 详细证明:(转载自matrix67) Matrix67: The Aha Moments 趣题:用 k × 1 的矩形覆盖 n × n ...

  2. java+selenium+testNG+Allure报表【新增截图到报表功能】

    1.pom.xml配置 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://w ...

  3. APP 自动化之系统按键事件(五)

    转载记录方便后续自己使用: 代码就一句driver.keyevent()括号内填入的是物理按键的数字代号 代号表: 电话键 KEYCODE_CALL 拨号键 5 KEYCODE_ENDCALL 挂机键 ...

  4. 【python】使用python十分钟创建个人聊天机器人教程

    以青云客和图灵机器人接口示范python创建个人聊天机器人教程 一.以青云客聊天机器人为例示范get请求 官方网址:http://api.qingyunke.com/ 1.接入指引 请求地址 http ...

  5. 前端调试工具(DevTools)

    前端调试工具(DevTools) 开启:F12 布局 切换PC和移动端 页面元素的快速测试技巧 保持元素的hover等状态:选中当前行点击右键 元素状态改变的监控技巧 触发断点后元素状态不会再改变,可 ...

  6. Qt分析:Qt中的两种定时器

    QTimer类的定时器 QTimer类定时器是QObject类定时器的扩展版或者说升级版,因为它可以提供更多的功能.比如说,它支持单次触发和多次触发. 使用QTimer类定时器的步骤: (1)创建一个 ...

  7. mui中openWindow方法的通用封装

    因为做项目跳转新页面和传参的场景太多了,而且有的页面需要的跳转动画也不一样,每次都写一大堆openWindow方法的配置项太麻烦,因此自己简单封装了一个小函数,用来方便webview页面的跳转和传参. ...

  8. Spark 安装部署与快速上手

    Spark 介绍 核心概念 Spark 是 UC Berkeley AMP lab 开发的一个集群计算的框架,类似于 Hadoop,但有很多的区别. 最大的优化是让计算任务的中间结果可以存储在内存中, ...

  9. 分享一下Eclipse中节省时间的技巧吧

    [初级技巧] ★★ 鼠标放在一个类名上面,会显示Javadoc.也可以通过屏幕下方的Javadoc面板来查看(你可以把它看成是MSDN的Java版). ★ 每个函数的第一行,左边有个圆圈,单击这个圆圈 ...

  10. [cf1491H]Yuezheng Ling and Dynamic Tree

    将其按照区间分块(即$[(i-1)K+1,iK]$作为一个块),并定义$f_{x}$表示$x$的祖先中编号最小且与$x$在同一个块内的节点,$f_{x}$可以通过$f_{a_{x}}$转移,即$f_{ ...