我们从 c++ 11(在 c++98/03 标准中也是如此)标准中知道(见下文),我们不能尝试替换 operator new 函数 - 全局空间中的放置形式,因为它已经定义。
18.6.1.3 安置表格 [new.delete.placement]
这些函数是保留的,C++ 程序可能不会定义取代标准 C++ 库 (17.6.4) 中的版本的函数。(3.7.4) 的规定不适用于 operator new 和 operator delete 的这些保留放置形式。
下面的代码片段中的第 2 点已经证明了这一点,按预期编译错误。
但是我仍然可以覆盖类级别中的新位置,效果很好,请参见下面片段中的第 (2) 点。这是为什么?不应该编译应该尽量防止(2)以及根据标准???
请参阅下面的我的片段:
class Test
{
public:
Test(int i):m_i(i) { cout << "Test::Test()" << endl; }
~Test() { cout << "Test::~Test()" << endl; }
//(1)class level override placement new
void* operator new (std::size_t size) throw (std::bad_alloc) {
cout << "My class level new" << endl;
return malloc(size);
}
//(2)class level override placement new
void* operator new (std::size_t size, void* ptr) throw() {
cout << "My class level non-throwing placement new" << endl;
return ptr;
}
private:
int m_i;
};
//<1>global replacement for operator new - single object form
void* operator new (std::size_t size) throw (std::bad_alloc) {
cout << "My global new" << endl;
return malloc(size);
}
//<2>global replacement for operator new - replcement form
//NB. This is a attempt that definitely fails according to c++ stadnard:
//does get compile error: error: redefinition of 'void* operator new(std::size_t, void*)'
/*
void* operator new (std::size_t size, void* ptr) throw() {
cout << "My global non-throwing placement new" << endl;
return ptr;
}
*/
int main() {
Test* p = new Test(1);
delete p;
cout << "" << endl;
void* mem = operator new(sizeof(Test));
Test* p2 = new(mem) Test(1);
p2->~Test();
operator delete (mem);
return 0;
}
以下是预期的输出:
My class level new
My global new
Test::Test()
Test::~Test()
My global new
My class level non-throwing placement new
Test::Test()
Test::~Test()
==================================================== ================================= 进一步澄清我的问题:
18.6.1.3 放置形式这些函数是保留的,C++ 程序不能定义替换 标准C++ 库 (17.6.4) 中的版本的函数。(3.7.4) 的规定不适用于这些保留的安置表格
运算符 new 和运算符 delete。
这解释了我的代码片段中 <2> 点处的预期编译错误,所以这个没问题。
但是为什么我可以在班级说明中的第(2)点取代班级级别的安置表格?