Last Updated: 2023-12-29 03:11:35 Friday
-- TOC --
我们一般使用new来创建对象得到其地址,使用delete销毁对象并释放内存:
T *p = new T{};
delete p;
操作符new干的事情:
操作符delete干的事情:
我们可以使用operator new/delete来将上面4个动作全部拆分开:
#include <iostream>
using namespace std;
struct xyz {
xyz(void) { cout << "constructor\n"; }
~xyz(void) { cout << "destructor\n"; }
};
int main(void) {
// only allocate memory
xyz *p { static_cast<xyz*>(operator new(sizeof(xyz))) };
// placement new
new(p) xyz{};
// call destructor explicitly
p->~xyz();
// deallocate memory
operator delete(p);
return 0;
}
operator new/delete仅仅申请或释放内存,而一般情况下的new/delete,是将其封装起来直接用了。
operator new有三种overload:
// might throw std::bad_alloc
void* operator new (std::size_t size) throw (std::bad_alloc);
// noexcept
void* operator new (std::size_t size, const std::nothrow_t ¬hrow_value) noexcept;
// placement noexcept
void* operator new (std::size_t size, void *ptr) noexcept;
前两种overload,涉及代码如何处理new失败的情况。
placement new其实就是直接返回传入的指针,但对象的constructor有可能throw,anyway,使用placement new的场景,都不会直接delete对象指针,内存的释放在别处。
对象可以overload创建自己的operator new/delete(前面有一篇总结new/delete的重载,那是全局的overload):
#include <iostream>
#include <cstdlib>
using namespace std;
struct xyz {
xyz(void) { cout << "* constructor\n"; }
~xyz(void) { cout << "* destructor\n"; }
void* operator new(size_t size) {
cout << "* overload new in class\n";
return malloc(size);
}
void* operator new(size_t size, const std::nothrow_t &x) noexcept {
cout << "* overload new without throw in class\n";
return malloc(size);
}
void* operator new(size_t size, void *p) noexcept {
cout << "* overload placement new in class\n";
return p;
}
void operator delete(void *p) {
cout << "* overload delete in class\n";
free(p);
}
};
int main(void) {
xyz *a { new xyz{} };
delete a;
xyz *b { new(std::nothrow) xyz{} };
delete b;
char *c { new char[24]{} };
xyz *d { new(c) xyz{} };
delete[] c;
return 0;
}
输出:
* overload new in class
* constructor
* destructor
* overload delete in class
* overload new without throw in class
* constructor
* destructor
* overload delete in class
* overload placement new in class
* constructor
在输出前加个
*
,立刻高大上了...
在xyz中overload delete是多余的,只是展示。最后的placement new,不可以调用delete,否则就是double free。
本文链接:https://cs.pynote.net/sf/c/cpp/202209023/
-- EOF --
-- MORE --