C++new的几种用法详解

1、new operator

        new operator 指的就是new操作符,它分为两个阶段的操作:

(1)调用::operator new 申请内存(相当于C语言的malloc)

(2)调用类的构造函数

#include<iostream>

class Fun{
public:
    Fun(){ std::cout<<"call constructor"<<std::endl;}
    ~Fun(){ std::cout<<"call destructor"<<std::endl;}
};

Fun* ptr1 = new Fun;  
delete ptr1;
ptr1 = nullptr;

// 输出结果
// call constructor
// call destructor

另外,需要注意的是new operator操作符是不能被重载的。

2、operator new

        operator new操作符单纯申请内存,并且是可以重载的函数。调用operator new申请内存,内存申请的大小为自定义类Fun的大小。使用operator new 和 operator delete并不会调用构造函数和析构函数,因为其仅仅具有申请内存的功能

Fun* ptr2 = (Fun*)::operator new(sizeof(Fun));
::operator delete ptr2;
ptr2 = nullptr;

// 加上::代表的是全局,因为operator可以重载
// 此时编译器并不会输出call constructor和call destructor
// 由此可以证明operator仅具有申请内存的功能

(1)重载operator new 操作符:

class Fun{
public:
    Fun(){ std::cout<<"call constructor"<<std::endl;}
    ~Fun(){ std::cout<<"call destructor"<<std::endl;}

    void* operator new(size_t size)
    {
        std::cout<<"operator new"<<std::endl;
        return ::operator new(size);
    }
    void operator delete(void* ptr)
    {
        std::cout<<"operator delete"<<std::endl;
        ::operator delete(ptr);
        ptr = nullptr;
    }
};  

Fun* ptr3 = new Fun;  
delete ptr3;

// 此时输出的是:  
// operator new
// call constructor
// call destructor
// operator delete 

由上述例子可以知道,Fun对象的构造与删除调用了重载的operator new和operator delete。

(2)operator new的另外一种重载版本:

class Fun{
public:
    Fun(){ std::cout<<"call constructor"<<std::endl;}
    ~Fun(){ std::cout<<"call destructor"<<std::endl;}

    void* operator new(size_t size)
    {
        std::cout<<"operator new"<<std::endl;
        return ::operator new(size);
    }
    void* operator new(size_t size, std::string str)
    {
        std::cout<<"operator new version 2: "<<str<<std::endl;
        return ::operator new(size);
    }
    void operator delete(void* ptr)
    {
        std::cout<<"operator delete"<<std::endl;
        ::operator delete(ptr);
        ptr = nullptr;
    }
};  

Fun* ptr4 = new("this is my func") Fun;  
delete ptr4;

// 此时输出的是:  
// operator new version 2: this is my func
// call constructor
// call destructor
// operator delete 

3、placement new

        placement new 又称为定位new运算符,它能够让程序员指定需要使用的位置。定位new运算符直接使用传递给它的地址,它不负责判断哪些内存单元已被使用,也不查找未使用的内存块。这将一些内存管理的负担交给了程序员。

char* buf[128]; // 创建一块内存池
int* p1 = new(buf)int[10];
for(int i=0;i<10;++i)
    p1[i]=i+1;

std::cout<<"buf的地址:"<<(int*)buf<<std::endl;
std::cout<<"p1数组的地址:"<<p1<<std::endl;

int* p2 = new(buf)int;
std::cout<<"p2的地址:"<<p2<<std::endl;

int* p3 = new(buf+10*sizeof(int))int;
std::cout<<"p3的地址:"<<p3<<std::endl;

/*
    输出结果:
    buf的地址:0x7ffe318d6d70
    p1数组的地址:0x7ffe318d6d70
    p2的地址:0x7ffe318d6d70
    p3的地址:0x7ffe318d6eb0
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

czy1219

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值