不一定,但不定义会导致行为不一致;c++20引入三路比较operator后,编译器可自动生成!=等比较运算符。

重载 operator== 时必须同时定义 operator!= 吗?
不一定,但不定义会导致行为不一致。C++20 引入了三路比较(operator),编译器能自动生成 !=、 等,但 C++17 及之前版本不会。
常见错误:只重载 operator==,然后在 if (a != b) 中调用默认的指针级比较(对类对象而言是未定义行为或误判)。
- 如果类有明确的“相等”语义(比如两个
Point坐标相同即相等),就该成对定义operator==和operator!=,且后者应返回!(a == b),而非手写逻辑 - C++20 下推荐优先写
operator,再加= default;但注意它要求所有成员都支持比较,且会抑制隐式生成的==(除非也显式声明operator==并= default) - 函数应声明为
const成员函数,并接受const&参数,避免无谓拷贝和修改风险
全局重载 operator 输出自定义类时,为什么编译报错 “no match for ‘operator
<p>最常见原因是没把重载函数声明为 <code>friend,或忘了加 std::ostream& 返回类型,导致链式调用(如 cout )失败。
使用场景:调试打印、日志输出,比写 print() 方法更自然,也兼容 STL 容器的泛型输出(配合 std::copy + std::ostream_iterator)。
立即学习“C++免费学习笔记(深入)”;
- 必须定义在类外部(不能是成员函数),签名固定为:
std::ostream& operator - 若需访问私有成员,得在类内加
friend std::ostream& operator - 函数末尾必须
return os;,否则cout 会在第二步崩掉 - 不要在函数里写
os —— 这会强制换行,破坏调用方对格式的控制权
operator[] 为什么要提供 const 和非 const 两个版本?
否则 const 对象无法用下标读取,而非常量对象却可能被意外写入 —— 这违反了 const 正确性原则。
典型场景:容器类(如自实现 Vector)、封装数组的包装类。用户期望 const Vec v{1,2,3}; int x = v[0]; 能通过,但 v[0] = 5; 编译失败。
- 非 const 版本返回
T&,支持赋值;const 版本返回const T&,只读 - 两者参数签名完全一致,仅靠 const 限定符区分,所以必须一个声明在 const 成员函数中,另一个在非 const 中
- 别偷懒只写一个返回
T&的版本 —— 那会让const对象调用失败,或触发隐式转换(如果有构造函数)引发意外行为
重载 new 和 delete 时,为什么程序崩溃在 operator new 内部?
大概率是没处理 size == 0 的情况,或没按标准要求抛出 std::bad_alloc。
使用场景:内存池管理、调试内存泄漏、对齐控制(如 SSE/AVX 要求 32 字节对齐)。但普通项目极少需要,滥用反而引入碎片和竞态。
-
operator new必须能处理size == 0,此时可返回任意非 null 指针(惯例返回static char dummy地址),但绝不能返回nullptr - 分配失败时必须抛
std::bad_alloc,不能返回nullptr—— C++ 标准规定new表达式会自动检查并抛异常,你的operator new是底层支撑,不能绕过 - 重载
operator delete时,第一个参数是void*,第二个可选参数是size_t(仅当operator new有对应 size 参数时才传入),二者签名要严格匹配
复杂点在于:类内重载会屏蔽全局版本,而继承体系中基类和派生类的 new 可能混用;最容易被忽略的是对齐要求 —— operator new 默认只保证 alignof(std::max_align_t),若类含 alignas(64) double x;,就得自己调用 aligned_alloc 或用 std::align 手动对齐。











