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
*/