问题描述
在他的书C ++编程语言(第4版)中,stroustroup提到全局运算符new& delete可以通过编写具有以下签名的全局函数来重载:
In his book C++ Programming Language(4th ed), stroustroup has mentioned that the global operator new & delete can be overloaded by writing global functions with the following signatures:
void* operator new(size_t); // use for individual object
void* operator new[](size_t); // use for array
void operator delete(void*, size_t); // use for individual object
void operator delete[](void*, size_t); // use for array
注意:传递size_t参数删除以确定正确的对象大小,具体来说,当删除基指针指向的派生对象时(基本需要虚拟dtor,以便传递正确的大小)。
NOTE: The size_t parameter is passed for the delete to determine the correct object size specifically when deleting a derived object pointed by a base pointer(base needs virtual dtor so that correct size is passed).
重载单个对象的全局版本。操作员新工作正常。操作符删除与上面的签名工作正常,但删除不会被调用。如果我更改删除签名,以便它只是一个void *,它会得到调用。可能的问题:
I was trying to overload the global versions for the individual object. The operator new works fine. The operator delete with the above signature works fine, but delete doesn't get called. If I change the delete signature so that it just takes a void *, it does get called. What could be the problem:
这里是代码:
void * operator new (size_t size)
{
cout << "My operator new called\n";
auto p = malloc(size);
return p;
}
void operator delete (void * ptr, size_t size) // Removing size_t parameter makes it work
{
cout << "My operator delete called\n";
free(ptr);
}
奇怪的是,如果我让操作员删除类,所以它的重载只是为那个类,删除签名(与size_t和没有size_t)似乎工作!
Strange is also the fact that if I make the operator delete a member of a class so that its overloaded just for that class, both delete signatures(with size_t and without size_t) seem to work!
在delete中传递size_t参数看起来合乎逻辑,我提到的注。但是,这种行为的原因是什么?我使用VS2013测试示例。
Passing size_t parameter in delete does seem logical as explained in the NOTE I had mentioned. But what could be the reason for this behavior? I am using VS2013 for testing out the examples.
推荐答案
从C ++ 1y草稿:
From the C++1y draft:
脚注83)如果要删除的对象的静态类型完成,不同于动态类型,析构函数不是
virtual,大小可能不正确,但是这种情况已经是未定义的,如上所述。
Footnote 83) If the static type of the object to be deleted is complete and is different from the dynamic type, and the destructor is not virtual, the size might be incorrect, but that case is already undefined, as stated above.
operator new(std::size_t)
operator new(std::size_t, const std::nothrow_t&)
operator new[](std::size_t)
operator new[](std::size_t, const std::nothrow_t&)
perator delete(void*)
operator delete(void*, const std::nothrow_t&)
operator delete[](void*)
operator delete[](void*, const std::nothrow_t&)
我注意到:接下来的四个是C ++ 1y中的新
note by me: The next four are new in C++1y
operator delete(void*, std::size_t)
operator delete(void*, std::size_t, const std::nothrow_t&)
operator delete[](void*, std::size_t)
operator delete[](void*, std::size_t, const std::nothrow_t&)
3使用程序的定义来代替实现(18.6)提供的默认版本。这种替换发生在程序启动之前(3.2,3.6)。程序的定义不应被指定为内联。
3 The program’s definitions are used instead of the default versions supplied by the implementation (18.6). Such replacement occurs prior to program startup (3.2, 3.6). The program’s definitions shall not be specified as inline. No diagnostic is required.
另请参阅在C ++ 1y中引入大小重新分配的提议:
Also take a look at the proposal which introduces sized deallocation in C++1y:
http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3536.html
这篇关于操作员删除签名意外行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!