2017-07-07 52 views
1

學習新增/刪除過載時,我無法理解一些問題。 問題:重載操作符new(),爲什麼構造函數被調用兩次?

  1. 爲什麼在構造函數,析構函數在刪除之前調用new?
  2. 爲什麼在使用:: new時會調用兩次構造函數?

我這裏附加代碼:


#include<iostream> 

using namespace std; 

class MyClass 
{ 
public: 
    MyClass() { 
     cout << "My Class is Constructed !" << endl; 

    } 

    ~MyClass() { cout << "My Class is Deleted ! " << endl; } 

    static void *operator new(size_t Size) 
    { 
     cout << "new call" << endl; 
     MyClass *p = ::new MyClass; 
     return p; 
    } 
    static void operator delete(void *p) 
    { 
     cout << "delete call" << endl; 
     ::delete p; 
    } 

}; 
int main() 
{ 
    MyClass *p = new MyClass; 
    delete p; 
    cin.get(); 
    return 0; 
} 

output: 
new call 
My Class is Constructed ! 
My Class is Constructed ! 
My Class is Deleted ! 
delete call 

+7

你不應該在'MyClass :: operator new'裏面執行':: new MyClass'。這個函數的目的是在不調用構造函數的情況下分配內存,但是你調用了一個構造函數(這就是爲什麼你會看到2個構造函數調用 - 對應於'new'表達式的兩個用法)。 –

+0

回答你的問題1,顯然必須先獲得存儲空間,然後才能構建對象;並且在釋放存儲器之前必須銷燬對象 –

+1

@ M.M:回答部分如下。 –

回答

3

爲什麼發生這種情況的原因是因爲當你分配一些與new,分配建設分兩個階段進行。第一個是實際分配,第二個是通過安置新建築。

您提供的重載僅用於分配內存(因此參數爲size_t),但您可以在類上調用new,該類將執行上述兩個步驟。你應該只在該函數中分配內存。所以改變你的功能

static void *operator new(size_t size) 
{ 
    return ::operator new(size); 
} 

而且你會看到只有一次構造的類。

+0

所以,刪除someting也有兩個階段,破壞和釋放內存?爲什麼析構函數只被調用一次? – JackChen

+1

@JackChen因爲你只調用它一次,就像構造函數被調用兩次,因爲你調用它兩次。 – EJP

+0

@JackChen EJP是對的,如果你在'operator delete'的重載中注意到,你已經在一個void指針上調用了':: delete',這只是釋放內存,你還沒有嘗試'static_cast' void指針指向MyClass的指針,然後調用析構函數,這就是爲什麼你只能得到一個析構函數調用 – Curious

相關問題