2014-09-27 31 views
1

我們試圖用特定參數重載delete []運算符。哪種方式可以稱之爲?我們使用GNU編譯器和編譯器獲得誤差隨所有這些樣品:重載delete []具有特定參數的運算符

#include<memory> 
using namespace std; 
typedef unsigned int P; 

struct A{ 
    static allocator<A>m; 
    P p; 
    void*operator new[](size_t s){return m.allocate(s);} 
    void operator delete[](void*p,int s){m.deallocate((A*)p,s);} 
    void operator delete[](void*p,size_t t,int s){m.deallocate((A*)p,s);} 
}; 

int main(){ 
    A*a=new A[10]; 
    //delete (5) []a;  //expected ',' before 'a' 
    //delete[5]a;   //expected ';' before ']' token 
    //delete[] (5) a;  //type ‘int’ argument given to ‘delete’, expected 
    //delete[]a (5);  //a’ cannot be used as a function 
    //delete[]((int)5)a; //type ‘int’ argument given to ‘delete’, expected pointer 
    //delete[]a((int)5); //‘a’ cannot be used as a function 
    return 0; 
} 
+2

不要將您收到的錯誤作爲解讀者的謎; **發佈他們,*逐字*,與您的問題**。 – WhozCraig 2014-09-27 20:00:36

+0

好吧..這樣做.. – ncomputers 2014-09-27 20:02:05

+1

數組被刪除像這樣:'delete [] a;' - 是否重寫了delete []'操作符。 – 2014-09-27 20:23:19

回答

3

有沒有「語法糖」這類位置缺失者的。
只有當位置new調用的構造函數拋出異常時,纔會調用放置刪除器(就像您聲明的那樣)。
然後程序將調用匹配的位置刪除器(相同的簽名)並嘗試釋放自定義分配的內存。

如果你仍然想調用這個方法,你必須調用手動操作:

A::operator delete[](a, 5); 

有它的工作原理在這裏一個很好的例子:http://en.cppreference.com/w/cpp/memory/new/operator_delete

請注意,在異常(刪除操作符在異常被觸發後調用):

#include <stdexcept> 
#include <iostream> 
struct X { 
    X() { throw std::runtime_error(""); } 
    // custom placement new 
    static void* operator new(std::size_t sz, bool b) { 
     std::cout << "custom placement new called, b = " << b << '\n'; 
     return ::operator new(sz); 
    } 
    // custom placement delete 
    static void operator delete(void* ptr, bool b) 
    { 
     std::cout << "custom placement delete called, b = " << b << '\n'; 
     ::operator delete(ptr); 
    } 
}; 
int main() { 
    try { 
    X* p1 = new (true) X; 
    } catch(const std::exception&) { } 
} 
+2

值得注意的是,這個手動調用並不等同於刪除表達式,甚至忽略了額外的參數。 delete [] p'調用析構函數,然後調用'operator delete []'函數,但除非知道數組的大小,否則無法手動調用正確數量的析構函數。 – aschepler 2014-09-27 20:51:41

+0

非常感謝! – ncomputers 2014-09-27 20:54:33

2

TL; DR:如果對象的構造函數拋出定製放置刪除器只被調用,並沒有明確的不能被稱爲操作員呼叫例如

Class::operator delete[](a, 10, etc..); 

析構函數將反正叫(你有另一個任務手工做你自己)。


詳細說明:

cppreference

重載操作者的刪除和操作者用額外的 用戶定義的參數( 「放置形式」,版本11-12)刪除[]可以是 像往常一樣在全局範圍聲明,並且如果正在分配的對象的構造函數引發異常,則由匹配的新表達式的 位置形式調用。

標準庫放置 形式操作的刪除(9-10)無法替代,只能 定製,如果放置新的表達並沒有使用::新 語法,通過提供類特定的位置刪除(17,18)與 匹配簽名:void T :: operator delete(void *,void *)或void T :: operator delete [](void *,void *)。

struct A{ 
    void* operator new[](std::size_t s){ 
     cout << "allocation 1" << endl; 
     ... 
     return ptr; 
     } 
    void* operator new[](std::size_t s, int){ 
     cout << "allocation 2" << endl; 
     ... 
     return ptr; 
     } 
    void operator delete[](void* s, std::size_t){ 
     cout << "deallocate 1" << endl; 
     ... 
    } 
    void operator delete[](void* s, std::size_t , int){ 
     cout << "deallocate 2" << endl; 
     ... 

    } 
}; 

int main(){ 
    A*a=new A[10]; 
    delete[] a; 
    A*b=new(5) A[10]; 
    A::operator delete[](b,sizeof(b)/sizeof(A*),5); // You'll have to call it manually! 
    return 0; 
} 
+0

非常感謝! – ncomputers 2014-09-27 20:53:35

+0

@ ncomputers.org不客氣:) – 2014-09-27 20:54:16