1 背景
在c++項(xiàng)目開(kāi)發(fā)中义起,極少數(shù)情況下就需要重載new
和delete
運(yùn)算符,比如:
- 使用內(nèi)存池
- 定位內(nèi)存泄露等
再看seastar
項(xiàng)目中class packet
對(duì)類(lèi)進(jìn)行了重載:
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);
}
...
};
當(dāng)然這里重載new
不是以上兩種需求而是特殊內(nèi)存分配場(chǎng)景目木。
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字節(jié)
int b; //4字節(jié)
};
int main()
{
X *p1 = new(4) X;
delete p1;
// std::cout << "----default version---" << std::endl;
// X *p2 = new X;
// delete p2;
return 0;
}
在這個(gè)示例中僅僅重載了new
续誉,并沒(méi)有重載delete
烤芦,下面我們?cè)囍剌ddelete
愕提。
#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字節(jié)
int b; //4字節(jié)
};
int main()
{
X *p1 = new(4) X;
delete p1;
return 0;
}
編譯竟然報(bào)錯(cuò)了:
error: no suitable ‘operator delete’ for ‘X’
delete p1;
也就是說(shuō)delete p1
調(diào)用的是默認(rèn)函數(shù),于是增加以下代碼:
static void operator delete(void* ptr)
{
std::cout << "default placement delete called." << std::endl;
::operator delete(ptr);
}
輸出結(jié)果是:
custom placement new called, size = 8|n = 4
default placement delete called
2.3 默認(rèn)new函數(shù)處理
因?yàn)橹剌d了new operator
华匾,所以也必須定義默認(rèn)的new
函數(shù)映琳,否則當(dāng)new一個(gè)默認(rèn)的對(duì)象時(shí)會(huì)出錯(cuò),如以下main
函數(shù):
int main()
{
X *p1 = new(4) X;
delete p1;
std::cout << "----default version---" << std::endl;
X *p2 = new X;
delete p2;
return 0;
}
編譯時(shí)會(huì)報(bào)錯(cuò)蜘拉,提示沒(méi)有默認(rèn)的new函數(shù)
刊头。