一、什么是取地址运算符的重载在 C 中一元运算符默认行为是返回对象在内存中的真实地址。但 C 允许你在类中重载它从而改变obj的返回值。cppclass T { public: T* operator() { return ...; } // 非 const 版本 const T* operator() const { return ...; } // const 版本 };一旦重载任何对T类型对象使用的表达式包括编译器生成的代码、模板库代码都会走你的自定义逻辑。二、为什么这个操作危险这是 C 中最不推荐重载的运算符之一原因破坏语言基本假设几乎所有代码都假设x拿到的是x的真实地址。标准库会出问题std::vector、智能指针、std::swap、placement new 等内部大量使用取地址。模板代码崩溃泛型代码无法预知你重载了。调试困难调试器、内存分析工具显示的信息可能误导。因此 C 标准专门提供了std::addressof()来绕过重载拿到真实地址cpp#include memory Proxy* realPtr std::addressof(proxy); // 不走 operator三、什么时候才应该重载它只有极少数场景场景说明代理对象 / 智能引用proxy返回被代理对象的地址让代理伪装成目标COM 接口某些 COM 智能指针需要obj得到接口指针方便QueryInterface反调试 / 代码混淆故意让攻击者分析困难特殊容器/迭代器适配极少数库内部实现绝大多数业务代码永远不应该重载。#include iostream #include memory // std::addressof #include cassert // 被代理的真实对象 struct Target { int value 42; }; // 代理对象重载取地址运算符返回 Target 的地址 class Proxy { public: explicit Proxy(Target* t) : target_(t) {} // 非 const 版本返回 Target* Target* operator() { std::cout [非const operator 被调用]\n; return target_; } // const 版本返回 const Target* const Target* operator() const { std::cout [const operator 被调用]\n; return target_; } private: Target* target_; }; int main() { Target real; Proxy p(real); // 1) 使用重载的 —— 返回的是 Target*不是 Proxy* Target* tp p; std::cout p 指向的 value tp-value \n; tp-value 100; std::cout 修改后 real.value real.value \n; // 2) const 对象走 const 版本 const Proxy cp(real); const Target* ctp cp; std::cout const cp 指向的 value ctp-value \n; // 3) 用 std::addressof 绕过重载拿到 Proxy 本身的真实地址 Proxy* realProxyAddr std::addressof(p); std::cout Proxy 真实地址 realProxyAddr \n; std::cout p (重载返回) tp \n; std::cout 两者不同 (realProxyAddr ! tp ? 是 : 否) \n; assert(realProxyAddr ! tp); // 证明重载生效 return 0; }