我遇到这一行是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将用户定义的类型作为其参数之一? 这是什么意思,我在这里错过了什么
答案 0 :(得分:5)
Stroustrup的引用显然适用于运算符重载。 C ++语言仅支持用户定义类型的运算符重载。这意味着重载函数(operator <something>
)必须是用户定义类型的成员,或者是具有至少一个用户定义类型参数的独立函数。这正是相关报价的含义。
然而,独立(非成员)operator new
和operator delete
函数不需要将用户定义类型的值作为其参数之一。这可能被视为与你的引用相矛盾的东西。
然而,实际上并没有矛盾。这些运算符实际上不是重载。当您提供自己的独立版operator new
/ operator delete
时,实际上替换库提供的版本。这是语言规范中的官方术语:替换,而不是重载。这就是为什么以上引用并不真正适用于operator new
和operator 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)
operator new
表达式中操作数的类型以及operator delete
的任何额外括号参数查找 new
和delete
。因此,它们可能会过载(并且new
受到重载解析),但是与其他运算符的机制不同。 (C ++03§13.5/ 5)
当他们使用原始内存时,他们从不处理指向客户端类类型的指针。 operator new
始终采用operator new
参数(可能还有其他参数,其中没有一个需要是用户定义的类型)并返回size_t
。 void *
始终采用operator delete
参数,并且可选择void *
,无论如何查找。
我可以想到两个原因:
size_t
或operator new
尝试访问返回的内存块中的对象始终是错误的。 (内存不用于构造对象,但是,这是公平的游戏。)operator delete
或operator new
可能会被多重和/或虚拟继承,因此无法使operator delete
指向尚未构建的void*
或者已经被破坏的子对象,任何伏都教。