如果构造函数在 new 调用期间抛出异常,则将调用具有相同参数的类似声明的 delete。因此,placement new 和 delete 应始终成对声明。
在这种情况下,删除将与数组删除具有相同的签名,编译器将无法在它们之间进行选择。
编辑添加示例代码和输出。
您的代码没有实现被禁止的全局数组放置新:
void * operator new( size_t bytes, size_t )
此程序将说明如何调用全局 new 和 delete。
#include <stdint.h>
#include <malloc.h>
#include <iostream>
#include <stdexcept>
using namespace std;
struct A
{
int a;
A( void )
: a( 1 )
{
cout << __LINE__ << " : A::A()" << endl;
throw logic_error( "That is .. illogical" );
}
};
// Placement new with size_t parameter
void * operator new( size_t bytes, size_t )
{
cout << __LINE__ << " : void * A::operator new( size_t bytes = " << bytes << ", size_t )";
void *p = malloc( bytes );
cout << " -> " << p << endl;
return p;
}
// C++11 : Array placement delete with size_t parameter
// C++14 : Array delete
void operator delete( void *p, std::size_t n )
{
cout << __LINE__ << " : void A::operator delete( void *p = " << p << ", size_t n = " << n << " )" << endl;
if (p)
free( p );
}
// Non-array new
void * operator new( size_t bytes )
{
cout << __LINE__ << " : void * A::operator new( size_t bytes = " << bytes << " )";
void *p = malloc( bytes );
cout << " -> " << p << endl;
return p;
}
// Non-array delete
void operator delete( void *p ) noexcept
{
cout << __LINE__ << " : void A::operator delete( void *p = " << p << " )" << endl;
if (p)
free( p );
}
// Array new
void * operator new[]( size_t bytes )
{
cout << __LINE__ << " : void * A::operator new[]( size_t bytes = " << bytes << " )";
void *p = malloc( bytes );
cout << " -> " << p << endl;
return p;
}
// Array placement new with size_t parameter
void * operator new[]( size_t bytes, size_t n )
{
cout << __LINE__ << " : void * A::operator new[]( size_t bytes = " << bytes << ", size_t n = " << n << " )";
void *p = malloc( bytes );
cout << " -> " << p << endl;
return p;
}
// C++11 : Array placement delete with size_t parameter
// C++14 : Array delete
void operator delete[]( void *p, std::size_t n )
{
cout << __LINE__ << " : void A::operator delete[]( void *p = " << p << ", size_t n = " << n << " )" << endl;
if (p)
free( p );
}
int main( int, char ** )
{
A *p = nullptr;
#if 1
try
{
cout << __LINE__ << " : ===== Array placement new allocate with size_t parameter. =====" << endl;
p = new( (size_t)4 ) A[ 3 ];
cout << __LINE__ << " : ===== Array placement new succeeded. =====" << endl;
}
catch (...)
{
}
cout << __LINE__ << " : ===== Array placement delete. =====" << endl;
delete[] p;
p = nullptr;
#endif
try
{
cout << __LINE__ << " : ===== Array new. =====" << endl;
p = new A[ 3 ];
cout << __LINE__ << " : ===== Array new succeeded. =====" << endl;
}
catch (...)
{
}
cout << __LINE__ << " : ===== Array delete. =====" << endl;
delete[] p;
p = nullptr;
cout << __LINE__ << " : ===== Complete. =====" << endl;
return 0;
}
使用 C++11 的 clang 3.4.2 编译得到以下结果:
$ clang++ --std=c++11 -o replace_new main.cpp && ./replace_new
88 : ===== Array placement new allocate with size_t parameter. =====
66 : void * A::operator new[]( size_t bytes = 12, size_t n = 4 ) -> 0x80048358
14 : A::A()
40 : void * A::operator new( size_t bytes = 33 ) -> 0x800483d8
76 : void A::operator delete[]( void *p = 0x80048358, size_t n = 4 )
49 : void A::operator delete( void *p = 0x800483d8 )
97 : ===== Array placement delete. =====
105 : ===== Array new. =====
57 : void * A::operator new[]( size_t bytes = 12 ) -> 0x80048358
14 : A::A()
40 : void * A::operator new( size_t bytes = 33 ) -> 0x800483d8
49 : void A::operator delete( void *p = 0x80048358 )
49 : void A::operator delete( void *p = 0x800483d8 )
114 : ===== Array delete. =====
118 : ===== Complete. =====
33 字节的分配是个例外。异常和数组都用同一个删除函数删除。
使用 C++14 规则编译会得到以下结果:
$ clang++ --std=c++1y -o replace_new main.cpp && ./replace_new
main.cpp:89:17: error: 'new' expression with placement arguments refers to non-placement 'operator delete'
p = new( (size_t)4 ) A[ 3 ];
^ ~~~~~~~~~
main.cpp:74:10: note: 'operator delete[]' declared here
void operator delete[]( void *p, std::size_t n )
^
1 error generated.
禁用无效部分并使用 C++14 规则编译会得到以下结果:
$ clang++ --std=c++1y -o replace_new main.cpp && ./replace_new
105 : ===== Array new. =====
57 : void * A::operator new[]( size_t bytes = 12 ) -> 0x80048358
14 : A::A()
40 : void * A::operator new( size_t bytes = 33 ) -> 0x800483d8
76 : void A::operator delete[]( void *p = 0x80048358, size_t n = 12 )
49 : void A::operator delete( void *p = 0x800483d8 )
114 : ===== Array delete. =====
118 : ===== Complete. =====
请注意,现在使用不同的删除函数删除了数组。当编译为 C++11 时,删除数组放置 new 的方法与第 76 行的删除函数相同。