在 C++ 中重载 new、delete
我遇到这一行是 stroustrup 操作符函数必须是用户定义类型的成员或至少采用一个用户定义类型的参数(重新定义 new 和 delete 操作符的函数不需要)。
不要操作符 new 和运算符删除将用户定义的类型作为其参数之一? 这是什么意思,我在这里错过了什么吗
i came across this line is 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 and operator delete take an user defined type as one of their arguments?
what does it mean, am i missing something here
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
Stroustrup 的引用显然适用于运算符重载。 C++ 语言仅支持用户定义类型的运算符重载。这意味着重载函数(
operator
)必须是用户定义类型的成员,或者是至少具有一个用户定义类型参数的独立函数。这正是所讨论的引文的含义。然而,独立(非成员)
operator new
和operator delete
函数不需要将用户定义类型的值作为其参数之一。这可能会被视为与您的引述相矛盾。但事实上,并不矛盾。这些运算符并没有真正超载。当您提供自己的独立
operator new
/operator delete
版本时,您实际上是在替换库提供的版本。这是语言规范中的官方术语:替换,而不是重载。这就是为什么上面的引用并不真正适用于operator new
和operator delete
。The quote from Stroustrup apparently applies to operator overloading. C++ language supports operator overloading for user-defined types only. This means that the overloading function (
operator <something>
) has to be either a member of user-defined type or be a standalone function with at least one argument of user-defined type. This is exactly what is meant by the quote in question.Yet standalone (non-member)
operator new
andoperator delete
functions are not required to take a value of user defined type as one of their arguments. This might be seen as something that contradicts your quote.However, in reality there's no contradiction. These operators are not really overloaded. When you provide your own versions of standalone
operator new
/operator delete
, you are actually replacing the library-provided ones. This is the official term from the language specification: replacement, not overloading. Which is why the above quote does not really apply tooperator new
andoperator delete
.如果您愿意,您可以重载普通的全局 new 运算符,为所有类添加功能(例如日志记录或泄漏检测),但无法调用 new 的旧定义/code> 运算符,因此您可能会在重新定义的
operator new
内部调用malloc()
来实际获取所需的内存。You can overload the normal global
new
operator, for all classes to add functionality (e.g. logging or leak detection) if you so desire, but there's no way to call the old definition of thenew
operator, so you'll probably be stuck callingmalloc()
from inside your redefinedoperator new
to actually get the memory that you need.a + b
只是a.operator+(b)
或operator+(a, b)
的语法糖。另一方面,new Foo(x, y, z) 不仅仅是运算符 new(Foo, x, y, z) 或类似内容的语法糖。它要复杂得多:
正如您所看到的,函数
operator new
仅仅分配内存,这只是操作符new
实际所做的一半。在我看来,将其命名为allocate_memory
或类似的名称会更有意义。它绝对不是像operator+
这样的运算符。a + b
is just syntactic sugar fora.operator+(b)
oroperator+(a, b)
.On the other hand,
new Foo(x, y, z)
is NOT just syntactic sugar foroperator new(Foo, x, y, z)
or something like that. It is way more complicated:As you can see, the function
operator new
merely allocates memory, which is only half of what the operatornew
actually does. In my opinion, it would have made far more sense to have named that thingallocate_memory
or something like that. It definitely IS NOT an operator likeoperator+
.根据
new
或delete
表达式中操作数的类型查找operator new
和operator delete
,以及new
的任何额外括号参数。因此,它们可能会被重载(operator new
受制于重载决策),但其机制与其他运算符不同。 (C++03 §13.5/5)当它们使用原始内存时,它们从不处理指向客户端类类型的指针。
operator new
始终采用size_t
参数(可能还有其他参数,其中都不需要是用户定义的类型)并返回void *
。operator delete
始终采用void *
参数和可选的size_t
,无论如何查找。我可以想到两个原因:
operator new
或operator delete
尝试访问返回的内存块中的对象始终是一个错误。 (内存不用于构造对象,但是,这是公平的游戏。)operator new
或operator delete
可以是乘法和/或虚拟继承,这样任何巫毒都不能使所讨论的void*
指向尚未构造或已销毁的子对象。operator new
andoperator delete
are looked up based on the type of the operand in thenew
ordelete
expression, and any extra parenthetical arguments tonew
. Thus they may be overloaded (andoperator new
is subject to overload resolution), but by a different mechanism than the other operators. (C++03 §13.5/5)As they work with raw memory, they never deal with pointers to the client class type.
operator new
always takes asize_t
argument (and possibly other arguments, none of which need be of user-defined type) and returnsvoid *
.operator delete
always takes avoid *
argument and optionally asize_t
, no matter how it was looked up.I can think of two reasons for this:
operator new
oroperator delete
to attempt to access an object within the returned block of memory. (Memory not used to construct objects, however, is fair game.)operator new
oroperator delete
may be multiply- and/or virtually-inherited, such that thevoid*
in question cannot be made to point to the not-yet-constructed or already-destroyed subobject, by any voodoo.