在 C++ 中重载 new、delete

发布于 2024-08-30 22:54:05 字数 161 浏览 2 评论 0原文

我遇到这一行是 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

夕色琉璃 2024-09-06 22:54:05

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

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

但事实上,并不矛盾。这些运算符并没有真正超载。当您提供自己的独立 operator new/operator delete 版本时,您实际上是在替换库提供的版本。这是语言规范中的官方术语:替换,而不是重载。这就是为什么上面的引用并不真正适用于operator newoperator 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 and operator 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 to operator new and operator delete.

多像笑话 2024-09-06 22:54:05

如果您愿意,您可以重载普通的全局 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 the new operator, so you'll probably be stuck calling malloc() from inside your redefined operator new to actually get the memory that you need.

晨敛清荷 2024-09-06 22:54:05

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

另一方面,new Foo(x, y, z) 不仅仅是运算符 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+ 这样的运算符。

a + b is just syntactic sugar for a.operator+(b) or operator+(a, b).

On the other hand, new Foo(x, y, z) is NOT just syntactic sugar for operator new(Foo, x, y, z) or something like that. It is way more complicated:

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

As you can see, the function operator new merely allocates memory, which is only half of what the operator new actually does. In my opinion, it would have made far more sense to have named that thing allocate_memory or something like that. It definitely IS NOT an operator like operator+.

慈悲佛祖 2024-09-06 22:54:05

根据 newdelete 表达式中操作数的类型查找 operator newoperator delete,以及 new 的任何额外括号参数。因此,它们可能会被重载(operator new 受制于重载决策),但其机制与其他运算符不同。 (C++03 §13.5/5)

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

我可以想到两个原因:

  • 它们处理原始内存,不包含构造对象。 operator newoperator delete 尝试访问返回的内存块中的对象始终是一个错误。 (内存用于构造对象,但是,这是公平的游戏。)
  • 类成员operator newoperator delete可以是乘法和/或虚拟继承,这样任何巫毒都不能使所讨论的 void* 指向尚未构造或已销毁的子对象。

operator new and operator delete are looked up based on the type of the operand in the new or delete expression, and any extra parenthetical arguments to new. Thus they may be overloaded (and operator 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 a size_t argument (and possibly other arguments, none of which need be of user-defined type) and returns void *. operator delete always takes a void * argument and optionally a size_t, no matter how it was looked up.

I can think of two reasons for this:

  • They deal with raw memory, not containing a constructed object. It is always an error for operator new or operator delete to attempt to access an object within the returned block of memory. (Memory not used to construct objects, however, is fair game.)
  • A class member operator new or operator delete may be multiply- and/or virtually-inherited, such that the void* in question cannot be made to point to the not-yet-constructed or already-destroyed subobject, by any voodoo.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文