C++中new 关键字有三个作用:
1. new operator = operator new + 构造函数 = 分配空间,调用构造函数
2. operator new = 分配空间
3. placement new = 不分配空间,调用构造函数
三种用法简单实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
#include <iostream> #include <cassert> using namespace std; class Tmp { public: Tmp(int n) : n_(n) { cout << "Tmp construction" << endl; } int n_; }; int main() { Tmp* t1 = new Tmp(100); // new operator = operator new + 构造函数 cout << t1->n_ << endl; char chunk[10]; Tmp* t2 = new (chunk) Tmp(200); // 在chunk空间中,创建Tmp对象 // placement new 就地创建对象,不分配内存 cout << t2->n_ << endl; assert((char*)chunk == (char*)t2); // 断言地址是否相等 // Tmp* t3 = (Tmp*)chunk; Tmp* t3 = reinterpret_cast<Tmp*>(chunk); // reinterpret_cast 重新解释的转换 cout << t3->n_ << endl; return 0; } |
operator new 和 placement new相关重载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
#include <iostream> #include <cassert> using namespace std; class Tmp { public: Tmp(int n) : n_(n) { cout << "Tmp construction" << endl; } ~Tmp() { cout << "~Tmp" << endl; } // 重载 operator new 操作 void* operator new(size_t size) { cout << "void* operator new(size_t size)" << endl; void* p = malloc(size); return p; } // 与operator new 相匹配的函数 void operator delete(void* p) { cout << "void operator delete(void* p)" << endl; free(p); } // 与operator new 相匹配的函数 优先级低于void operator delete(void* p),但是可以共存 void operator delete(void* p, size_t size) { cout << "void operator delete(void* p, size_t size)" << endl; free(p); } // 打印文件和行信息 void* operator new(size_t size, const char* file, long line) { cout << file << ":" << line; void* p = malloc(size); return p; } // 打印文件和行信息,与之相匹配的delete函数 void operator delete(void* p, const char* file, long line) { cout << file << ":" << line; free(p); } // placement new,不分配内存 void* operator new(size_t size, void* p) { cout << "void* operator new(size_t size, void* p)" << endl; return p; } // placement new 相匹配的delete void operator delete(void* , void*) { cout << "void operator delete(void* , void*)" << endl; } int n_; }; // 全局 operator new, 如 char* str = new char; void* operator new(size_t size) { cout << "global void* operator new(size_t size)" << endl; void* p = malloc(size); return p; } // 与全局operator new相匹配 void operator delete(void* p) { cout << "void operator delete(void* p)" << endl; free(p); } // 全局 operator new, 如 char* str = new char; void* operator new[](size_t size) { cout << "global void* operator new[](size_t size)" << endl; void* p = malloc(size); return p; } // 与全局operator new相匹配 void operator delete[](void* p) { cout << "void operator delete[](void* p)" << endl; free(p); } int main() { Tmp* t1 = new Tmp(100); // new operator = operator new + 构造函数 cout << t1->n_ << endl; delete t1; char* str = new char[10]; // 全局operator new delete[] str; char chunk[10]; Tmp* t2 = new (chunk) Tmp(200); // 在chunk空间中,创建Tmp对象,placement new 就地创建对象,不分配内存 t2->~Tmp(); // placement new中调用了构造函数,那么就应该调用析构函数,但是t2并不是在堆上分配的内存 // 不应该用delete, 所以应该显示调用析构函数 assert((char*)chunk == (char*)t2); // Tmp* t3 = (Tmp*)chunk; Tmp* t3 = reinterpret_cast<Tmp*>(chunk); // reinterpret_cast 重新解释的转换 cout << t3->n_ << endl; Tmp* t4 = new(__FILE__, __LINE__) Tmp(400); delete t4; return 0; } |