我编写的以下代码必须同时调用放置释放和分配函数。
#include <iostream>
using namespace std;
struct A
{
void * operator new [] (size_t t, int, int)
{
cout << "3 parameters allocation" << endl;
return ::operator new[](t);
}
void operator delete [] (void *p, int, int)
{
cout << "3 parameters deallocation" << endl;
return ::operator delete[](p);
}
};
int main()
{
A *a = new (5,5) A[10]; //operator new [] (size_t, int, int) invoked
delete [] a; //Error. Overload resolution is failed.
}
5.3.4 / 22说N3797:
展示位置释放函数的声明与 如果具有相同的位置分配功能的声明 参数数量,参数变换后(8.3.5)全部 参数类型除了第一个是相同的。如果查找找到了 单匹配解除分配函数,该函数将被调用; 否则,不会调用释放函数。
这不是C++11
中的实现,还是我的误解?
答案 0 :(得分:9)
如果提供了特定于类的释放函数,则除非具有一个或两个参数的特定于类的释放函数,否则未通过作用域解析运算符作为前缀的 delete-expression 格式不正确可用的:
10 - 如果类型完成并且如果解除分配函数查找同时找到通常的释放函数,只有指针参数和通常的释放函数同时具有指针参数和大小参数,那么所选的释放函数应该是一个有两个参数。否则,所选的释放函数应为具有一个参数的函数。
所以你需要:
void operator delete[](void*);
,void operator delete[](void*, size_t);
或::delete[] a
。答案 1 :(得分:1)
A *a = new(5, 5) A[10];
A::operator delete[](a,5,5);
在Visual C ++ 2013上,这非常有用
答案 2 :(得分:1)
如果您想要访问operator delete
中的原始展示位置新参数,则必须将它们存储在已分配的内存块中,然后再检索它们。例如(Live at Ideone):
struct A
{
static void * operator new [] (size_t t, int first, int second);
static void operator delete [] (void *p, size_t t);
static void operator delete [] (void *p, int first, int second)
{
cout << "3 parameters deallocation: " << first << ", " << second << endl;
return ::operator delete[](p);
}
};
// simple POD struct to store the placement parameters
struct info {
int first_param, second_param;
};
void* A::operator new [] (size_t t, int first, int second)
{
cout << "3 parameters allocation: " << first << ", " << second << endl;
// allocate sizeof(info) extra space to store the parameters
auto const p = ::operator new[](t + sizeof(info));
auto const pinfo = reinterpret_cast<char*>(p) + t;
auto const tmp = info{first, second};
std::copy_n(reinterpret_cast<const char*>(&tmp), sizeof(info), pinfo);
return p;
}
static void A::operator delete [] (void *p, std::size_t t) {
// retrieve the parameters that we stored in operator new [].
auto const pinfo = reinterpret_cast<const char*>(p) + t;
auto tmp = info{};
std::copy_n(pinfo, sizeof(info), reinterpret_cast<char*>(&tmp));
cout << "Deleting with original parameters: " << tmp.first_param << ", " << tmp.second_param << endl;
::operator delete[](p);
}