【M8】了解各种不同意义的new和delete
1、首先考虑new operator,new operator 可以认为做了三件事情:a、调用operator new分配一块内存;b、在这块内存上调用构造方法构造对象;返回指针。
2、operator new的声明如下:
void* operator new(size_t size)
和C中的malloc一样,operator new只负责分配内存。
3、考虑,string* ps = new string("hello"); 相当于做了下列事情:
a、void* memory = operator new (sizeof(string));
b、在*memory上面,调用string::string("hello"),构造对象;
c、返回指针,string* ps = static_cast<string*>(memory).
4、上面通过operator new 试图分配一块内存。这存在两个问题:a、底层接口通过一定算法分配一块可用的内存,有可能是耗时的;b、也许无法分配一块可用的内存。因此,就有了下面的需求:我提前分配一块内存,然后在这块内存上调用构造方法,构造对象,该怎么办呢?如下:
Widget* ConstructWidgetOnBuffer(void* buffer, int widgetSize)
{
return new (buffer) Widget(widgetSize);
}
这里的new operator不同于正常的new operator,中间有个(buffer)。这里的new operator调用placement new,placement new 声明如下:
void* operator new(size_t, void* location)
{
return location;
}
5、考虑,delete operator,可认为做了两件事:a、指向对象调用析构方法;b、执行operator delete释放内存。如下:
string* ps; delete ps; 相当于:
ps->~string();
operator delete(ps);
6、如果只是处理原始,未设初值的内存,不应该使用new operator和delete operator,而应该使用operator new和operator delete,如下:
void* buffer = operator new(20);
operator delete(buffer)
这类似于C中的方法malloc和free。
7、特别注意:new与delete的使用要匹配。分别是:
a、operator new 对应operator delete,前面不构造,后面不析构;
b、new operator对应delete operator;
c、对于placement new 不能使用delete operator,因为前者并不分配内存,只是使用已有的内存构造对象,而delete operator会释放内存,而这块内存别人可能还在使用。因此,应该只是调用析构方法;
d、是否带有[],new operator 和delete operator要匹配。如:string* ps = new string[10]; delete [] ps; delete时中括号放前面。
【M8】了解各种不同意义的new和delete的更多相关文章
- 不同意义的new和delete
补充说明: new/delete是运算符而非函数,operator new/delete并非是new/delete的重载.事实上,我们无法自定义new/delete的行为: operator new/ ...
- JavaScript小细节点罗列
共勉! 属性访问表达式 众所周知,JavaScript为属性的访问定义了两种语法方式: 表达式.标识符 // 表达式(指定对象) 标识符(指定需要访问的属性的名称) 表达式[表达式] //表达式1(指 ...
- ###《More Effective C++》- 操作符
More Effective C++ #@author: gr #@date: 2015-05-21 #@email: forgerui@gmail.com 五.对定制的"类型转换函数&qu ...
- More Effective C++ 35 条款
一.基础议题(basics) 条款1:仔细区别 pointers 和 references(Distinguish between pointers and references) 一个基本的语法问题 ...
- JavaScript小细节点罗列(1)
共勉! 属性访问表达式 众所周知,JavaScript为属性的访问定义了两种语法方式: 表达式.标识符 // 表达式(指定对象) 标识符(指定需要访问的属性的名称) 表达式[表达式] //表达式1(指 ...
- 【C++】new和delete表达式与内存管理
new和delete表达式可以用来动态创建和释放单个对象,也可以用来动态创建和释放动态数组. 定义变量时,必须指定其数据类型和名字.而动态创建对象时,只需指定其数据类型,而不必为该对象命名.new表达 ...
- MoreEffectiveC++Item35(操作符)(条款5-8)
条款5 对定制的"类型转换函数"保持警惕 条款6 区别increment/decrement操作符的前值和后置形式 条款7 千万不要重载&&,||,和,操作符 条款 ...
- More Effective C++ 35个改善方法
美·Scott Meyers 侯捷 More Exceptional C++: 40 New Engineering Puzzles, Programming Problems, and Soluti ...
- C++ 内存分配操作符new和delete详解
重载new和delete 首先借用C++ Primer 5e的一个例子: string *sp = new string("a value"); ]; 这其实进行了以下三步操作: ...
随机推荐
- 【web】web欢迎页面执行servlet
<!-- servlet名 --> <welcome-file-list> <welcome-file>Begin_page</welcome-file> ...
- 【转】ios app 应用内购买配置完全指南
转自:http://blog.sina.com.cn/s/blog_4b55f6860100sbfb.html 第一印象觉得In-App Purchase(简称IAP)非常简单.Apple提供的大量文 ...
- Delphi or函数的用法
function GetFlag(a: string): Integer;var I: Integer;begin Result := 0; for I := 0 to 3 - 1 do begin ...
- asp.net夜话之十一:web.config详解
转:http://blog.csdn.net/zhoufoxcn/article/details/3265141 在开发中经常会遇到这样的情况,在部署程序时为了保密起见并不将源代码随项目一同发布,而我 ...
- C# DataGridView的列对象属性探讨 (未完待续)
比较难的几个属性的释义[1]:
- lightoj 1022
直接算即可,特别要注意精度 #include<cstdio> #include<cmath> int main(){ int t, CASE(0); double r; sca ...
- 【LeetCode 169】Majority Element
Given an array of size n, find the majority element. The majority element is the element that appear ...
- Face++接口封装
本节使用doCurlGetRequest函数来封装Face++的接口请求.我们在class文件夹下的faceStub.php文件中实现 一个faceStub类,封装请求Face++的相关接口. 实现代 ...
- Android的Eclipse升级笔记
Eclipse优化: 1.可以删除的插件有: EGit CVS Mylyn cdt 1.不用多次加载布局容器的版本: ADT-22.3.0 adt-bundle-windows-x86-2013103 ...
- 【转载】epoll的使用
select,poll,epoll简介 select select本质上是通过设置或者检查存放fd标志位的数据结构来进行下一步处理.这样所带来的缺点是: 1 单个进程可监视的fd数量被限制 2 需要维 ...