编写高质量代码——区分new的三种形态

new (内存管理运算符)有三种形态:
■new operator
与运算符 sizeof 类似,是语言内建的,不能重载,不能改变其行为,无论何时何地所做的有且只有三件事:
1)从堆中划分一块区域
2)自动调用构造函数,动态地创建某种特定类型的数据
3)返回该区域的指针


例如:string *pStr=new string("Memory Management");实做以下事情:
//为string 对象分配 raw 内存
void *memory=operator new(sizeof(string));
//调用构造函数,初始化内存中的对象   //对于内置类型,该步骤忽略。
call string::string() on memory; 
//获得对象指针
string *pStr=static_cast<string*>(memory);
Note:new operator 执行过程中,与其他的两种形态都发生密切关系:第一步的内存申请是通过 operator new完成;第二步,编译器会自动调用placement new,相应的,在调用 delete operator时同样会生成调用placement delete析构函数的代码。调用什么构造函数,则由 placement new 来决定。
========================================================
■operator new
具有和加减乘除运算符一样的地位,因此可以可以重载。
返回条件:
1)内存分配成功
2)抛出bad_alloc异常(从堆中得到一段空间,如果失败,调用new_hander,继续重复前面的操作,直到抛出异常)。
---------------------------------------------------------
void* operator new(size_t size);/*类似C中的malloc函数,可以重载,operator new 和 operator delete 是一一对应的,要成对重载 */
返回值是void*,因为该函数返回的是一个未经处理的指针,是一块未初始化的内存。

例如:
#include <iostream>
using namespace std;
class A{
public :
    A(){};
    ~A(){};
    void* operator new(size_t size);
};
void* A::operator new(size_t size){
    cout << "Our operator new..." << endl;
    return ::operator new(size);/* 调用了全局的 new 来进行内存分配。该全局 new 也是可以重载的,但是在全局空间中重载函数将会改变所有默认的 operator new 的行为方式 */
}
int main(void){
    A *a = new A;
    return 0;
}
========================================================
■placement new
用来实现选择合适的构造函数。
void *_CRTDECL operator new(size_t ,void *_Where) _THROW0(){
//construct array with placement at_Where
    return (_Where);
}
void *_Where:获得指向内存的指针,只有这样我们才知道该把 placement new 初始化完成的对象放在哪里。
========================================================
总结:
1)如果实在堆上建立对象,那么应该使用 new operator,它会为你提供最为周全的服务。
2)如果仅仅是分配内存,那么应该调用 operator new,但初始化不在它的工作职责之内。如果对默认的内存分配过程不满意,重载 operator new。
3)如果想在一块已经获得的内存里建立一个对象,那就应该调用 placement new。通常不建议使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值