重载新的,在C ++中删除

时间:2010-05-03 04:18:08

标签: c++ operator-overloading

我遇到这一行是stroustrup An operator function must either be a member or take at least one argument of a user-defined type (functions redefining the new and delete operators need not).

Dont operator new和operator delete将用户定义的类型作为其参数之一? 这是什么意思,我在这里错过了什么

4 个答案:

答案 0 :(得分:5)

Stroustrup的引用显然适用于运算符重载。 C ++语言仅支持用户定义类型的运算符重载。这意味着重载函数(operator <something>)必须是用户定义类型的成员,或者是具有至少一个用户定义类型参数的独立函数。这正是相关报价的含义。

然而,独立(非成员)operator newoperator delete函数不需要将用户定义类型的值作为其参数之一。这可能被视为与你的引用相矛盾的东西。

然而,实际上并没有矛盾。这些运算符实际上不是重载。当您提供自己的独立版operator new / operator delete时,实际上替换库提供的版本。这是语言规范中的官方术语:替换,而不是重载。这就是为什么以上引用并不真正适用于operator newoperator delete

答案 1 :(得分:3)

如果您愿意,您可以重载正常的全局new运算符,以便为所有类添加功能(例如日志记录或泄漏检测),但是无法调用new的旧定义运算符,因此您可能会在重新定义的malloc()内调用operator new而无法实际获取所需的内存。

答案 2 :(得分:2)

a + b只是a.operator+(b)operator+(a, b)的语法糖。

另一方面,new Foo(x, y, z)不仅仅是operator new(Foo, x, y, z)的语法糖或类似的东西。它更复杂:

void* address = operator new(sizeof(Foo)); // here is the behavior you can replace
try {
    new(address) Foo(x, y, z);
} catch (...) {
    operator delete(address);
}

正如您所看到的,函数operator new仅仅分配内存,这只是运算符new实际执行的内存的一半。在我看来,将这个东西命名为allocate_memory或类似东西会更有意义。它绝对不是像operator+那样的运算符。

答案 3 :(得分:0)

根据{{​​1}}或operator new表达式中操作数的类型以及operator delete的任何额外括号参数查找

newdelete 。因此,它们可能会过载(并且new 受到重载解析),但是与其他运算符的机制不同。 (C ++03§13.5/ 5)

当他们使用原始内存时,他们从不处理指向客户端类类型的指针。 operator new始终采用operator new参数(可能还有其他参数,其中没有一个需要是用户定义的类型)并返回size_tvoid *始终采用operator delete参数,并且可选择void *,无论如何查找。

我可以想到两个原因:

  • 它们处理原始内存,不包含构造对象。 size_toperator new尝试访问返回的内存块中的对象始终是错误的。 (内存用于构造对象,但是,这是公平的游戏。)
  • 班级成员operator deleteoperator new可能会被多重和/或虚拟继承,因此无法使operator delete指向尚未构建的void*或者已经被破坏的子对象,任何伏都教。