C++ 重载具有特定参数的delete[]运算符
我们试图用特定参数重载delete[]运算符。哪一个是正确的称呼?我们使用GNU编译器并获得所有这些示例的编译器错误:C++ 重载具有特定参数的delete[]运算符,c++,delete-operator,C++,Delete Operator,我们试图用特定参数重载delete[]运算符。哪一个是正确的称呼?我们使用GNU编译器并获得所有这些示例的编译器错误: #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 oper
#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;
}
#包括
使用名称空间std;
typedef无符号整数P;
结构A{
静态分配器;
P;
void*运算符new[](size_t s){返回m.allocate(s);}
void运算符delete[](void*p,int s){m.deallocate((A*)p,s);}
void操作符delete[](void*p,size_t t,int s){m.deallocate((A*)p,s);}
};
int main(){
A*A=新的A[10];
//删除(5)[]a;//应在“a”之前加上“,”
//删除[5]a;//在“]”标记之前应为“;”
//delete[](5)a;//应键入给定给“delete”的“int”参数
//delete[]a(5);//a'不能用作函数
//delete[]((int)5)a;//键入给定给“delete”的“int”参数,应为指针
//delete[]a((int)5);//'a'不能用作函数
返回0;
}
TL;DR:仅当对象的构造函数抛出并且在没有显式运算符调用(例如
Class::operator delete[](a, 10, etc..);
析构函数无论如何都不会被调用(另一项任务你必须自己手动完成)
详情: 从 运算符delete和运算符delete[]的重载以及附加的 用户定义的参数(“放置表格”,版本11-12)可以是 与往常一样在全局范围内声明,并由匹配的 如果对象的构造函数 正在分配的将引发异常 标准图书馆布局 操作员删除表单(9-10)不能替换,只能 如果placement new表达式未使用::new,则进行自定义 语法,通过提供特定于类的位置删除(17,18)和 匹配签名:void T::运算符delete(void*,void*)或void 运算符delete[](void*,void*) 结构A{ void*运算符新[](标准::大小){ cout这种位置删除器没有“语法糖”。
只有当placement new调用的构造函数抛出异常时,才会调用placement deleter(如您所声明的)。
然后程序将调用匹配的placement deleter(相同的签名),并尝试释放自定义分配的内存 如果仍要调用此方法,则必须手动调用运算符:
A::operator delete[](a, 5);
这里有一个很好的例子说明它是如何工作的:
注意类析构函数中的异常(触发异常后调用delete操作符):
#包括
#包括
结构X{
X(){throw std::runtime_error(“”;}
//自定义放置新
静态void*运算符新(标准::大小_t sz,布尔b){
std::不能将收到的错误作为一个谜留给读者解密;将其逐字发布,并附上您的问题。数组的删除方式如下:delete[]a;
-您是否覆盖了delete[]
运算符。您知道您的分配器分配sizeof(a)
倍于应有的内存?请参阅:是的,我们知道:我们正在尝试重载new和delete运算符,以允许以面向对象的方式收缩数组。下面是有关此主题的更多信息。非常感谢您的时间、答案和评论!值得注意的是,此手动调用并不等效删除表达式,甚至忽略额外的参数。delete[]p
调用析构函数,然后调用operator delete[]
函数,但除非知道数组的大小,否则无法手动调用正确数量的析构函数。
A::operator delete[](a, 5);
#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&) { }
}