c++类重载operator new和delete运算符(一)
2018-07-29 本文已影响11人
dnsir
1 背景
在c++项目开发中,极少数情况下就需要重载new
和delete
运算符,比如:
- 使用内存池
- 定位内存泄露等
再看seastar
项目中class packet
对类进行了重载:
class packet {
...
void* operator new(size_t size, size_t nr_frags = default_nr_frags) {
assert(nr_frags == uint16_t(nr_frags));
return ::operator new(size + nr_frags * sizeof(fragment));
}
// Matching the operator new above
void operator delete(void* ptr, size_t nr_frags) {
return ::operator delete(ptr);
}
// Since the above "placement delete" hides the global one, expose it
void operator delete(void* ptr) {
return ::operator delete(ptr);
}
...
};
当然这里重载new
不是以上两种需求而是特殊内存分配场景。
2 重载示例
2.1 最基本重载new和delete
#include <iostream>
struct X {
X(){}
static void *operator new(std::size_t sz, int n)
{
std::cout << "custom placement new called, size = " << sz << "|n = " << n << std::endl;
return ::operator new(sz);
}
public:
int a; //4字节
int b; //4字节
};
int main()
{
X *p1 = new(4) X;
delete p1;
// std::cout << "----default version---" << std::endl;
// X *p2 = new X;
// delete p2;
return 0;
}
在这个示例中仅仅重载了new
,并没有重载delete
,下面我们试着重载delete
。
#include <iostream>
struct X {
X(){}
static void *operator new(std::size_t sz, int n)
{
std::cout << "custom placement new called, size = " << sz << "|n = " << n << std::endl;
return ::operator new(sz);
}
static void operator delete(void* ptr, int n)
{
std::cout << "custom delete called1" << std::endl;
return ::operator delete(ptr);
}
public:
int a; //4字节
int b; //4字节
};
int main()
{
X *p1 = new(4) X;
delete p1;
return 0;
}
编译竟然报错了:
error: no suitable ‘operator delete’ for ‘X’
delete p1;
也就是说delete p1
调用的是默认函数,于是增加以下代码:
static void operator delete(void* ptr)
{
std::cout << "default placement delete called." << std::endl;
::operator delete(ptr);
}
输出结果是:
custom placement new called, size = 8|n = 4
default placement delete called
2.3 默认new函数处理
因为重载了new operator
,所以也必须定义默认的new
函数,否则当new一个默认的对象时会出错,如以下main
函数:
int main()
{
X *p1 = new(4) X;
delete p1;
std::cout << "----default version---" << std::endl;
X *p2 = new X;
delete p2;
return 0;
}
编译时会报错,提示没有默认的new函数
。