2015-12-15 34 views
1

我正在學習C++放置新的代碼。C++ Placement new and構造函數調用

class Cell { 
    public: 
    Cell() { 
     printf("default constructor by %s\n", __func__); 
    } 
    Cell(int ina) : a(ina) { 
     printf("customized constructor.\n"); 
    } 
    ~Cell() {} 
    void* operator new(size_t);        // Operator new. 
    void* operator new(size_t, Cell*p) { 
     return p; 
    } 
    private: 
    int a;             // tmp variable. 
}; 

// Global variable. 
Cell global_cell; 

void* Cell::operator new(size_t size) { 
    printf("start running the placement new\n"); 
    Cell* ptr = new (&global_cell) Cell; 
    printf("the cell pointer is %p and the global address is %p\n", ptr, &global_cell); 
    return ptr; 
} 


int main() { 
    printf("====\n"); 
    Cell *ptr = new Cell; 
    printf("====\n"); 
} 

這是我得到的輸出:

default constructor by Cell 
===== 
start running the placement new 
default constructor by Cell 
the cell pointer is 0x60107c and the global address is 0x60107c 
default constructor by Cell 
===== 

我所知道的第一個「默認構造函數」來源於global_cell開始。但爲什麼在那之後我得到了兩個「默認構造函數」?我錯過了關於展示位置的新內容嗎?另外,我怎樣才能實現與第二個非默認的構造函數接受一個輸入整數的位置?

+0

對不起,這是一個錯字,當我嘗試手動編輯帖子。 – Jes

回答

0

您正在以錯誤的方式爲班級實施自定義operator new

operator new對於一個類,應該只提供原始內存放置實例的位置,而不是創建對象。使用new來初始化一個對象(因爲您沒有指定任何參數,所以在您的案例中使用默認構造函數)。

如果您想使用新的佈局和參數傳遞只寫

new (memory_address) MyObject(arg1, arg2); 

,但請注意,使用放置新的排序是一個替代來定義自定義operator new爲類。在後者只需調用正常的分配與

new MyObject(arg1, arg2); 

使用您的自定義的分配器(不過這應該只是提供足夠和正確對齊的內存)。

+0

謝謝你的回答!我只知道我唯一要做的就是返回內存地址。 :) – Jes

2
new (&global_cell) Cell 

operator new超載是一個默認的建設,new Cellmain是其他。

operator new只能分配內存,不能構造對象;之後會自動調用相關的構造函數。

使用放置新的與非默認構造函數也不是很複雜:(也就是說,沒有差異的「常規」 new

new (&global_cell) Cell(2) 

0

你讓他們當你調用「新小區」:

Cell *ptr = new Cell; 
Cell* ptr = new (&global_cell) Cell; 

運營商新後調用構造函數總是被稱爲

+0

我明白了。謝謝! – Jes