這里說的定位new運算符,是一種相對於普通的new運算符,可以指定內存地址的運算符,程序直接使用我們提供的地址,不管它是否已經被使用,而且可以看到新值直接覆蓋在舊值上面。
定位new運算符直接使用傳遞給它的地址,它不負責判斷哪些內存單元已被使用,也不查找未使用的內存塊
由於本質上定位new運算符並不開辟新的內存,也就不應該用delete去釋放它
單來說就是new運算符只是返回傳遞給它的地址,並將其強制轉換為void *,以便能夠賦給任何指針類型。
#include<iostream> #include<string> using namespace std; const int BUF = 512; class JustTesting { private: string words; int number; public: JustTesting(const string& s = "Just Testing", int n = 0) { words = s; number = n; cout << words << " constructed" << endl; } ~JustTesting() { cout << words << " destroyed" << endl; } void show() const { cout << words << " ," << number << endl; } }; int main() { char* buffer = new char[BUF]; JustTesting *pc1, *pc2; pc1 = new(buffer)JustTesting; pc2 = new JustTesting("Heap1", 20); cout << "Memory block address" << endl << "buffer: " << (void*)buffer << " heap: " << pc2 << endl; cout << pc1 << ": "; pc1->show(); cout << pc2 << ": "; pc2->show(); JustTesting *pc3, *pc4; //pc3 = new (buffer)JustTesting("Bad Idea", 6); //pc3直接占用了pc1的內存區域,這樣一來如果pc1中有new分配的成員變量,將造成內存泄漏, //因此更好的方式是 pc3 = new (buffer+sizeof(JustTesting)) JustTesting("Better Idea",6); pc4 = new JustTesting("Heap2", 10); cout << "Memory Contents" << endl; cout << pc3 << ": "; pc3->show(); cout << pc4 << ": "; pc4->show(); delete pc2; delete pc4; //由於delete buffer並不會出發buffer內對象的析構函數,所以只能手動調用其析構函數 //需要注意調用析構函數的順序,由於晚創建的對象可能依賴早創建的對象,因此析構的順序應該與創建順序相反,另外,僅當析構了所有對象之后,才能釋放用於存儲這些對象的緩沖區 pc3->~JustTesting(); pc1->~JustTesting(); delete[] buffer; //delete pc1; 因為buffer和pc1實際上指向同一個地址,因此如果注釋掉上面一行,打開這里,也可以正常運行,但邏輯上卻是沒有道理的 cout << "done" << endl; cin.get(); return 0; }
