new operator new操作符
operator new 操作符new
placement new 定位new
string *ps = new string("Memory Management");
这里的new是new 操作符。这里共有两个步骤的工作要做:
①为对象申请空间 ②调用构造函数初始化内存中的对象
new 操作符总是做这两件事,不可以任何方式改变其行为。
但是你可以改变步骤①如何为对象申请空间。
new 操作符是通过 operator new这个函数为对象申请空间。
operator new 的声明形式
void* operator new(size_t size);//在做其他形式重载时也要保证第一个参数必须为size_t类型
函数的返回值是 void*,参数size确定分配多少内存
该函数调用时与普通函数一样
ST *pt = operator new(sizeof(ST));
placement new的作用是在已经被分配但是尚未处理的(raw)内存中构造一个对象。它是一个特殊的operator new
void* operator new(size_t, void *p)//参数size_t没有名字,但是为了防止编译器警告必须加上 { return p; }
在使用placement new时调用者已经获得了指向内存的指针,因为调用者知道对象应该放在
哪里。placement new必须做的就是返回传递给它的指针。
总结:如果你想在堆上建立一个对象,应该使用new 操作符,它既分配内存又为对象调用构造函数;
如果你只想分配内存,就调用operator new函数,它不会调用构造函数;
如果你想定制自己的在堆对象被建立时的内存分配过程,你应该写自己的operator new 函数,然后使用
new操作符,new操作符会调用你定制的operator new。
如果你想在一块已经获得指针的内存里建立一个对象,应该使用palcement new.
#include<iostream> #include<vld.h> using namespace std; class ST { private: char *ptr; public: ST(const char *str = ""):ptr("") { cout<<"Object was built. "<<endl; if(str == NULL) { this->ptr = new char[1]; this->ptr[0] = ‘\0‘; } else { this->ptr = new char [strlen(str)+1]; strcpy(ptr, str); } } ~ST() { cout<<"Object was free. "<<endl; delete []this->ptr; ptr = NULL; } void* operator new(size_t, void *p)//placement new { return p; } void operator delete(void *p) { cout<<"---"<<endl; free(p); } }; void* operator new(size_t t) { void *p = malloc(t); return p; }void* operator new[](size_t t) { void *p = malloc(t); return p; }void operator delete[](void *p) { cout<<"--[][]\n"; free(p); return; } void main() { ST *pt = (ST*)operator new (sizeof(ST)); //使用重载的operator new 为对象pt分配空间 new(pt)ST("Hello"); //这里调用placement new,同时也调用了构造函数。前两行代码等价于在未重载new时 ST *pt = new ST("Hello"); pt->~ST(); //通过pt指针可直接调用析构函数,但是不可调用构造函数 operator delete (pt); //调用operator delete函数 后行代码等价于在未重载delete时 delete pt
运行结果
为了避免内存泄漏,每个动态内存分配必须与一个等同相反的deallocation对应。
函数operator delete与delete操作符的关系和operator new与new操作符一样。
注意,在使用placement new在内存建立对象时,应避免使用delete操作符。
应该显式调用对象的析构函数来解除构造函数的影响。
在为对象数组申请空间时必可重载 operator new[] 函数而不再使用operator new函数。
例如
ST *pt = new ST[3];
这个过程共调用3次构造函数
将上例主函数修改为
void main() { ST *pr = new ST[3]; delete[] pr;//[]一定不可缺少 }
运行结果为
原文地址:https://www.cnblogs.com/area-h-p/p/10345880.html