2014-09-27 26 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