-
参考
-
普通的
new
new
是C++里很常用的操作符号,比如说创建一个对象A* = new A();
,这个操作回执行下面3个步骤- 调用
operator new
分配内存,operator new(sizeof(A))
,需要注意的是new
是一个操作符号,operator new
是一个函数,前者不能重载,后者能 - 调用构造函数
A::A();
,进行初始化 - 返回内存首地址
- 调用
- 然后上面说到,
operator new
是能重载的,如果没有去重载,调用的则是C++提供的默认的operator new(size_t)
,如果想下面代码一样重载了 - 那么,在创建
TestNew
时就要这样TestNew* pTestNew = new("hahaha", 1) TestNew();
,在new
后填上参数,然后就会去执行重载后的operator new
函数
class TestNew : public TestBase { public: TestNew(); ~TestNew(); void Test(); void* operator new (size_t size, const char* msg, int ret); void operator delete(void* pointer); } void* TestNew::operator new (size_t size, const char* msg, int ret) { std::cout << "operator new size " << size << " with string " << msg << " ret " << ret << std::endl; return ::operator new(size); } void TestNew::operator delete(void* pointer) { std::cout << "operator delete" << std::endl; ::operator delete(pointer); }
- 然后
operator new
有三种形式- 第一种,
void* operator new (std::size_t size) throw (std::bad_alloc);
,默认的,成功时返回对象内存地址,失败时抛异常 - 第二种,
void* operator new (std::size_t size, const std::nothrow_t& nothrow_constant) throw();
,失败时不抛异常 - 第三种,
void* operator new (std::size_t size, void* ptr) throw();
,这个就是下面说的placement new
,这种不能重载
- 第一种,
- 同理,
operator delete
也一样
-
placement new
- 系统内存分配的速度其实相对来说是不快的,特别是内存中碎片很多,此时又需要申请一块大内存时,就会更慢,所以如果是需要频繁申请内存的场景下,就可以使用
placement new
了。 - 其原理就是在已申请的内存上创建对象,因为少了申请内存的操作(因为提前申请好了),所以效率会高些。
- 使用时,需要传入内存的首地址,
Test* pTest = new (buff)Test;
- 这个内存地址可以是堆里的,也可以是栈里的
- 使用上面的方法创建对象时,并不会申请一块新内存,而是在传入的内存地址处创建对象,然后调用对应的构造函数,然后释放时,需要显式调用析构函数
- 这种方式比较适合用于需要频繁申请内存对象的场合,比如接收消息,每次收到客户端发过来的消息,需要申请一块内存去处理,用完后又需要将其释放,如果使用普通的申请方式,就会导致申请次数很多,而且容易产生内存碎片,所以可以使用
placement new
的方式,将申请内存的操作省去,直接复用内存,做对象的构造和析构即可
class Test { public: Test() {} ~Test() {} int GetId() { return m_nId; } void SetId(int nId) { m_nId = nId; } private: int m_nId; } void DoTest() { char* pBuff = new char[sizeof(Test)]; Test* pTest = new (buff)Test; pTest->SetId(1); pTest->~Test(); delete []buff; }
- 系统内存分配的速度其实相对来说是不快的,特别是内存中碎片很多,此时又需要申请一块大内存时,就会更慢,所以如果是需要频繁申请内存的场景下,就可以使用