深入剖析C++中的三种new

  1. new运算符
  2. Operator new()函数
  3. placement new

我们平时调用的new运算符底层调用的就是Operator new()函数(功能和malloc一模一样),如果是内置类型或者没有重载new运算符的自定义类型,那么将调用全局Operator new(),如果重载了将调用局部的Operator new(),如果这个类型有构造函数,new还是调用构造函数(注意调用构造函数之前还会吧operator new()的返回值检查一下,如果等于0那么就不调用构造函数)

验证1:new运算符底层调用的就是Operator new()函数

class A
{
public:
    A(){ cout << "构造" << endl; }
    int a;
};
int test2()
{
    A *b = new A;
    return 0;
}

这里写图片描述

验证2:内置类型或者没有重载new运算符的自定义类型,那么将调用全局Operator new(),重载了将调用局部的Operator new()

没有重载的汇编代码刚才已经看了,现在看一个重载之后的。
这里写图片描述
区别很明显吧!!

验证3:如果这个类型有构造函数,new还是调用构造函数
还是第一段代码
这里写图片描述

第二段代码(没有构造)
这里写图片描述
再看一个内置类型,和上面一模一样
这里写图片描述

验证4:构造函数之前还会吧operator new()的返回值检查一下,如果等于0那么就不调用构造函数
我们来重载一下new操作符

class A
{
public:
    A(){ cout << "构造" << endl; }
    int a;
    void * operator new(size_t size)
    {
        cout << "dong" << endl;
        return NULL;
    }
};
int test2()
{
    A *b = new A;
    return 0;
}

看一下汇编
这里写图片描述
最终执行的结果
这里写图片描述

如果我的代码这样写

class A
{
public:
    A(){ cout << "构造" << endl; }
    int a;
    void * operator new(size_t size)
    {
        cout << "dong" << endl;
        return (void *)1;
    }
};
int test2()
{
    A *b = new A;
    return 0;
}

结果就是
这里写图片描述

为啥是这样应该都能明白吧!!

验证5:为啥说功能和malloc一模一样

class A
{
public:
    A(){ cout << "构造" << endl; }
    int a;
    void * operator new(size_t size)
    {
        cout << "dong" << endl;
        return (void *)1;
    }
};
int test2()
{
    A *b = (A *)operator new (12);
    A *c = (A *)malloc(12);
}

看一下源码 VC/crt/src/newop.cpp

void *__CRTDECL operator new(size_t count) _THROW1(_STD bad_alloc)
    {   // try to allocate size bytes
    void *p;
    while ((p = malloc(count)) == 0)
        if (_callnewh(count) == 0)
            {   // report no memory
            _STD _Xbad_alloc();
            }
    return (p);
    }

其实底层就是调用的malloc

有人会奇怪我不是重载了operator new()么?为啥不打印?
因为我们调用的是全局operator new()啊,C++编译器在全局给我们默认创建了一个
那我们怎么调用自己类中的operator new()呢?没有对象我们能调用类中的函数么?
1.没有类对象我们是可以调用类中部分函数的。
2.更何况重载了operator new()编译器会自动帮我们把这个函数改为static的,也就是静态的。
所以不管是哪一方面都是可以调用的
这里写图片描述

然后我们看一看 定位new
这里写图片描述
下面 new A 就等价于上面两句话

注意上面这幅图我没有重载operator new(),因为如果重载了,定位new的时候会发生参数不匹配问题
如果你实在想调用自定义的operator new()可以这样写

A *p = (A*)operator new(sizeof(A));
A *a = new (p) A;

new的知识还是蛮多的

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值