重载delete操作符

6
我想在我的类中覆盖 delete 操作符。这是我正在尝试做的,但不成功。
class Complex{              
    void *operator new(size_t s);
    void operator delete(void *ptr);
};

void Complex::operator delete(void *ptr){
    delete ptr;
}

我遇到了一个错误:
删除void*未定义

1
你可能想要使用 ::delete ptr; - Mats Petersson
方法签名看起来不对,new 没有 size_t 参数(只有 new[] 有),但是 delete 确实 有一个 size_t 参数。 - Anton Kovalenko
1
你不能重载delete操作符,它是一个语言关键字。你所做的是重载operator delete,它是被delete操作符调用的函数。这听起来可能像是文字游戏,但这是一个重要的区别。 - Pete Becker
删除操作不应该有 size_t 作为参数。因为我想写成:Complex c = new Complex(); delete c; - user2036677
1
“operator delete” 必须撤销 “operator new” 所做的任何操作。你能展示一下 “operator new” 吗? - Robᵩ
3个回答

5
正如错误消息所示,您不能删除一个 void*。请尝试以下操作:
// See http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=40

#include <new> // for size_t

class Complex
{
public:
 Complex() {}
 ~Complex() {}
 static void* operator new (size_t size) {
  return new char[size];
 }
 static void operator delete (void *p) {
  return delete[] static_cast<char*>(p);
 }
};

int main () {
  Complex *p = new Complex;
  delete p;
}

4

你的声明是正确的。问题出在实现你的 operator delete 的代码上:它使用了关键字 delete 而不是调用全局的 operator delete。应该像这样编写:

void Complex::operator delete(void *ptr) {
    ::operator delete(ptr);
}

假设你的 operator new 使用了全局的 operator new

那么,在新的方法中,只需要写:return (::operator new(s)); 就可以了吗? - user2036677
@AntonioKumar - 是的,静态成员函数可以编写为调用全局 operator new。当然,这引出了一个问题,即为什么会有它,因为在它的缺席时它只是执行编译器所做的操作。 - Pete Becker

1

通过delete删除是相当奇怪的,但删除void*是未定义行为。

此外,size_t不是内置类型:它在<cstddef>中定义。

这可能是可以的:

#include <cstddef>

class Complex
{              
    void *operator new(size_t s);
    void operator delete(void *ptr);
};

void* Complex::operator new(size_t s)
{ return new char[s]; } //allocate a buffer of s bytes

void Complex::operator delete(void *ptr)
{ delete[] static_cast<char*>(ptr); } //deallocate the buffer

实际上,我们在 new / delete 中一致地分配/释放适当大小的缓冲区。
在 new 中,我们要求系统为我们提供所需的字节。我使用 char[s],因为 char 是 memory size_t 的单位:根据定义,sizeof(char) == 1。
在 delete 中,我们必须将由 ptr 标识的字节归还给系统。由于我们将它们分配为 char[],因此我们必须将它们作为 char[] 删除,因此使用 delete[] 和 char* 强制转换。

那么,请问这两行代码在做什么? - user2036677
在这里使用static_cast,而不是reinterpret_cast - GManNickG
1
@EmilioGaravaglia:使用 static_cast 来取消隐式转换(char* 隐式转换为 void*),reinterpret_cast 太强了。你没有重新解释任何内容,只是合理地撤销了隐式转换。 - GManNickG

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接