C++中的new用法总结
前段时间复习面试的时候,看到这个问题经常有问到,我这个小白就看了些博客和书,总结一下。
new可以说是个一个关键字,也可以说是一个运算符,并且可以被重载。
1、new operator
这个就是平时最经常用的new,用法如下程序所示:
class A
{
public:
A(int i) :a(i){}
private:
int a;
}; int main()
{
A* example = new A();
}
new operator实际上执行了以下三个步骤:
1、调用operator new分配内存(后面要说的第二种new),如果类本身定义了operator new,那么会调用类自己的operator new,而不是全局的;
2、调用A的构造函数A::A(int);
3、返回相应的指针
2、operator new
operator new不调用构造函数,而仅仅分配内存,有两个版本,前者抛出异常,后者当失败时不抛出异常,而是直接返回:
void* operator new (std::size_t size);
void* operator new (std::size_t size, const std::nothrow_t& nothrow_value) noexcept;
可以看到,operator new的作用有点类似与C语言中的malloc,有的地方说operator new的底层实现可以是malloc。
C++中可以用set_new_handler()设置抛出bad_alloc()异常时调用的处理函数,<<Effective C++>>有几个条款很详细描述了具体做法。
我还是太菜了,水平不够,不太能理解自定义异常处理函数的内容...T T
class A
{
public:
A(int i) :a(i){}
void* operator new(size_t size)
{
cout << "call A::operator new" << endl;
return malloc(size);
}
void operator delete(void* p)
{
cout << "call A::operator delete" << endl;
return free(p);
}
void* operator new(size_t size, const nothrow_t& nothrow_value) noexcept
{
cout << "call A::operator new (noexcept)" << endl;
return malloc(size);
}
void operator delete(void* p, const nothrow_t& nothrow_value) noexcept
{
cout << "call A::operator delete (noexcept)" << endl;
free(p);
}
private:
int a;
}; int main()
{
A* example1 = new A();
delete example1;
A* example2 = new(nothrow) A();
delete example2;
}
用一个小例子可以证明一下,确实调用的是自定义operator new/delete,而不是全局的。
3、placement new
placement new仅在一个已经分配好的内存指针上调用构造函数,基本形式如下:
void* operator new (std::size_t size, void* ptr) noexcept;
placement new不需要抛出异常,因为它自身不分配内存。
同时,ptr指针是已经分配好的,可能在栈上也可能在堆上,如下面的例子:
class A
{
public:
A(int i) :a(i){}
int getValue(){ return a; }
private:
int a;
}; int main()
{
A* p1 = new A(); //在堆上分配
A A2(); //在栈上分配
A* p2 = &A2;
cout << "placement new前的值: " << p1->getValue() << " " << p2->getValue() << endl; A* p3 = new(p1) A(); //在p1的位置上构造
A* p4 = new(p2) A(); //在p2的位置上构造
cout << "placement new后的值: " << p1->getValue() << " " << p2->getValue() << endl;
}
第一次输出的是1,2;在相应位置构造后,输出值变为3,4。
C++中的new用法总结的更多相关文章
- [转载]C#中MessageBox.Show用法以及VB.NET中MsgBox用法
一.C#中MessageBox.Show用法 MessageBox.Show (String) 显示具有指定文本的消息框. 由 .NET Compact Framework 支持. MessageBo ...
- C#中string.format用法详解
C#中string.format用法详解 本文实例总结了C#中string.format用法.分享给大家供大家参考.具体分析如下: String.Format 方法的几种定义: String.Form ...
- SQL中distinct的用法
SQL中distinct的用法 1.作用于单列 2.作用于多列 3.COUNT统计 4.distinct必须放在开头 5.其他 在表中,可能会包含重复值.这并不成问题,不过,有时您也许希望仅仅列出 ...
- Oracle 中 decode 函数用法
Oracle 中 decode 函数用法 含义解释:decode(条件,值1,返回值1,值2,返回值2,...值n,返回值n,缺省值) 该函数的含义如下:IF 条件=值1 THEN RETURN(翻译 ...
- jQuery中Animate进阶用法(一)
jQuery中animate的用法你了解多少呢?如果仅仅是简单的移动位置,显示隐藏,哦!天哪你在浪费资源!因为animate太强大了,你可以有很多意想不到的用法!让我们一起研究一下吧~~ 首先要了解j ...
- [转载]js中return的用法
一.返回控制与函数结果,语法为:return 表达式; 语句结束函数执行,返回调用函数,而且把表达式的值作为函数的结果 二.返回控制,无函数结果,语法为:return; 在大多数情况下,为事件处理函 ...
- js中this的用法
经过近几周的模拟面试题,我查询了一些资料,今天就来说说,在js中this的用法吧.方法有四:第一,用作全局变量,第二,用作表该对象,第三,用作构造函数,第四,用作call和applay
- jQuery中eq()方法用法实例
本文实例讲述了jQuery中eq()方法用法.分享给大家供大家参考.具体分析如下: 此方法能够获取匹配元素集上的相应位置索引的元素. 匹配元素集上元素的位置索引是从0开始的. 语法结构: 复制代码 代 ...
- php中return的用法实例分析
本文实例讲述了php中return的用法.分享给大家供大家参考.具体分析如下: 首先,它的意思就是返回;return()是语言结构而不是函数,仅在参数包含表达式时才需要用括号将其括起来.当返回一个变量 ...
- mysql中event的用法详解
一.基本概念mysql5.1版本开始引进event概念.event既“时间触发器”,与triggers的事件触发不同,event类似与linux crontab计划任务,用于时间触发.通过单独或调用存 ...
随机推荐
- Elasticsearch 学习笔记 Elasticsearch及Elasticsearch head安装配置
一.安装与配置 1.到官网下载Elasticsearch,https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.6. ...
- Computer form factor
http://en.wikipedia.org/wiki/Motherboard_form_factor Computer form factor From Wikipedia, the free e ...
- HDU 2108 Shape of HDU (判断是不是凸多边形 叉乘)
Shape of HDU Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- Linux下mount FreeBSD分区
假设须要从第二块硬盘复制文件.该硬盘格式化为UFS 2文件系统.怎样mount 由FreeBSD创建的UFS 2文件系统到Ubuntu系统上呢? UFS文件系统广泛的使用在不同的操作系统(比如:HP- ...
- ruby简单的基础 2
1.代码块 代码块是用大括号或者do...end括起来的一系列代码.{ #this is a block} do #this is a blockend [1,2,3,4,5].each {|i| p ...
- DSL 如何工作
DSL 如何工作 http://computer.howstuffworks.com/dsl.htm 当你连接到因特网时,你可能是通过一个调制解调器 (modem),或办公室的局域网,或者一个电缆调制 ...
- 深入浅出 - Android系统移植与平台开发(九)- Android系统system_server及Home启动
3.3 Zygote守护进程与system_server进程 Android的执行环境和Java执行环境有着本质的差别,在Android系统中每一个应用程序都是一独立的进程,当一个进程死掉时,不会影响 ...
- MUI-折叠面板效果accordion
在做开发的过程中我们经经常使用到折叠面板. 那我们来看下折叠面板到底是怎么使用. 废话不多说. 代码粘下来: <!DOCTYPE html> <html> <head&g ...
- DRF 之 认证组件
1.认证的作用? 我们知道,当我们在网站上登陆之后,就会有自己的个人中心,之类的可以对自己的信息进行修改.但是http请求又是无状态的,所以导致我们每次请求都是一个新的请求,服务端每次都需要对请求进行 ...
- Git 和 SVN 之间的五个基本区别
GIT不仅仅是个版本控制系统,它也是个内容管理系统(CMS),工作管理系统等.如果你是一个具有使用SVN背景的人,你需要做一定的思想转换,来适应GIT提供的一些概念和特征.所以,这篇文章的主要目的就是 ...