不是必须,但不定义会出问题:c++20起若operator==为default或满足三路比较要求,编译器自动生成operator!=;c++17及之前需显式定义,推荐复用return !(a == b)。

重载 operator== 时必须同时定义 operator!= 吗?
不是必须,但不定义会出问题。C++20 起如果只定义 operator==,编译器能自动生成 operator!=(前提是 operator== 是 default 或满足三路比较要求);但 C++17 及之前,!= 不会自动推导——用户写 a != b 就直接报错:「no match for ‘operator!=’」。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 用 C++20?优先写
operator==并加= default,让编译器生成对称的!= - 用 C++17 或更早?必须显式定义
operator!=,且推荐复用==:return !(a == b); - 别在
operator!=里手写逻辑——容易和==不一致,尤其涉及浮点、指针或自定义相等语义时
operator 必须是全局函数,不能是类成员?
对。因为流输出操作符左操作数是 std::ostream&(比如 std::cout),而成员函数的隐式 this 指针永远是左操作数。如果把 operator 声明为 <code>MyClass 的成员函数,调用就变成 obj ,完全反了。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 声明为非成员函数,通常放在类定义外的头文件中,加
friend访问私有成员 - 签名必须是:
std::ostream& operator - 函数末尾务必返回
os,否则链式调用(如cout )会断掉 - 不要返回
void,也不要返回局部std::ostream对象——常见崩溃源头
重载 operator[] 为什么要提供 const 和非 const 两个版本?
因为 const 对象只能调用 const 成员函数。如果你只写了非 const 版本 T& operator[](size_t i),那么对 const 对象调用 arr[0] 就会编译失败。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 必须成对实现:
T& operator[](size_t i)和const T& operator[](size_t i) const - 非 const 版本通常直接调用 const 版本再做 const_cast(不推荐),更安全的是提取公共逻辑到私有辅助函数
- 别在 const 版本里返回
T&——破坏 const 正确性,编译器会拦住 - 下标越界检查建议统一在辅助函数里做,避免重复逻辑
重载 new 和 delete 容易踩哪些内存坑?
最常见的是匹配错误:重载了类内 operator new,却没重载对应参数个数的 operator delete。例如定义了 void* operator new(size_t, std::nothrow_t),但没配 void operator delete(void*, std::nothrow_t),一旦构造函数抛异常,就会调用默认 delete,导致内存泄漏或崩溃。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 每定义一个
operator new(含 placement、nothrow 等变体),必须定义参数完全一致的operator delete - 类内重载只影响该类对象的分配;全局重载影响所有类型,慎用
- placement
new不分配内存,所以对应的delete是空操作——但仍要声明,否则异常路径不可靠 - 别在
operator new里直接throw std::bad_alloc();应先尝试分配,失败再 throw
运算符重载本身不难,难在边界条件和生命周期细节——比如 const 正确性、异常安全、内存匹配、隐式转换控制。这些地方一漏,轻则行为不符合直觉,重则 crash 在生产环境里,而且很难复现。









