3

有人可以向我解释 C++ 入门第 5 版中的这一段:

术语:new 表达式与 operator new 函数

库函数 operator new 和 operator delete 的名称具有误导性。与其他运算符函数(例如 operator=)不同,这些函数不会重载 new 或 delete 表达式。事实上,我们无法重新定义 new 和 delete 表达式的行为。

new 表达式总是通过调用 operator new 函数来获取内存,然后在该内存中构造一个对象来执行。删除表达式总是通过销毁对象然后调用运算符删除函数来释放对象使用的内存来执行。

通过提供我们自己对 operator new 和 operator delete 函数的定义,我们可以改变内存的分配方式。但是,我们不能改变 new 和 delete 操作符的这个基本含义。

我没有看到operator neworoperator delete与任何其他重载运算符(如赋值运算符)之间的区别=。那么“被误导性命名”是什么意思?我们都知道我们不会重载类似的表达式,fObj + fObj但我们重载了运算符而不是表达式本身。

事实上,我发现这一段本身就具有误导性。毕竟我们可以“滥用”任何可重载的运算符以及来自哪个运算符newdelete那么他在本段中的意思是什么?谢谢!

4

1 回答 1

6

C++ 中的大多数运算符不受任何显式语义或要求的约束。唯一真正的例外是operator new并且operator delete由于它的特殊用途,这就是它所指的。

例如,让我们考虑operator==.

尽管让这个运算符执行某种比较并返回 a来表示相等是常规的(并且是明智的) ——这实际上不是 C++ 语言所要求的。bool

事实上,定义operator==返回完全不相关的东西是完全可能的——可能是 an int, a std::string,或者更奇怪的东西,比如std::tuple。当然,它实际上不需要进行任何比较。

实际上,C++ 中大多数运算符的语义在约定上是微弱的,但不是语言所要求的。

这与operator new和形成对比operator deletenewC++ 中的表达式将始终operator new在调用返回的指针处开始动态对象的生命周期。无论是new (p) T{...}用于placement-new 表达式,new T{...}使用global-new操作符,还是一些new(args,...) T{...}用于自定义operator new——它必须返回某种形式的指针以在for 开始生命周期T

同样,delete必须结束该生命周期,并调用operator delete以释放该生命周期的底层存储。这有效地强制语义operator newoperator delete分别执行某种形式的分配机制和某种形式的清理机制。实际上不可能定义newdelete做一些奇怪的事情(如 的情况operator==),因为调用这些运算符的隐含行为将简单地中断(如果它完全编译)。

这就是为什么引用提到operator new/的行为operator delete无法重新定义的原因;基本含义永远是固定的。

于 2021-05-05T23:11:09.713 回答