重载 和 -> 必须是类类型非静态成员函数; 应返回 T& 或 const T& 而非 T;-> 必须返回指针或重载了 -> 的类类型,且二者常成对出现但语义可不对称,空状态需主动检查。

重载 * 和 -> 的前提:必须是类类型成员函数
只有类(或结构体)的成员函数才能重载 * 和 ->;全局函数重载不被允许。这是语言硬性限制,不是设计选择——编译器需要确保操作符语义与指针行为对齐,而只有类能封装“像指针但不是指针”的逻辑(比如智能指针、迭代器)。如果你在非类作用域里写 operator*,会直接报错:error: 'operator*' must be a non-static member function。
operator* 返回什么?别盲目返回 T&
返回类型取决于你模拟的是哪种“可解引用对象”:
- 若模拟原生指针(如
std::unique_ptr<t></t>),应返回T&(非常量左值引用),否则无法赋值:*ptr = 42; - 若模拟只读访问(如某些 const 迭代器),返回
const T&更安全 - 若内部存储的是值而非指针(比如包装了
std::optional<t></t>),则需检查是否有值,否则解引用未初始化对象会触发未定义行为
常见错误:返回 T(值拷贝)——这会让 *p = x 编译失败,因为右值不能绑定到非 const 引用;也违背“解引用应提供对所指对象的直接访问”这一直觉。
operator-> 必须返回指针或重载了 -> 的类型
这是最容易卡住的地方:operator-> 的返回值类型必须满足:要么是指针(T*),要么是另一个重载了 operator-> 的类类型。编译器会自动链式调用 ->,直到最终得到一个原生指针。
立即学习“C++免费学习笔记(深入)”;
典型写法:
struct Wrapper {
int* ptr_;
int* operator->() { return ptr_; } // 直接返回指针
};或者链式委托:
struct Inner { int value = 0; };
struct Outer {
Inner inner_;
Inner* operator->() { return &inner_; } // 返回指向 Inner 的指针
};错误示例:返回 Inner& 或 Inner —— 编译直接拒绝,提示 error: '->' must return a pointer or a class with overloaded '->'。
两个操作符常成对出现,但语义不必完全对称
虽然 -> 通常通过 * 实现(比如先 *this 再取成员),但标准库中更常见的是反向依赖:operator-> 返回指针,operator* 解引用该指针。两者职责明确:
-
operator*提供对目标对象的引用访问 -
operator->提供对目标对象成员的间接访问入口
注意:如果你在 operator-> 里调用了 operator*,要小心循环调用风险(比如 return &(*this); 而 operator* 又调回 operator->)。实际项目中,绝大多数自定义指针类都让 operator-> 直接返回缓存的原始指针,而非依赖 *。
真正容易被忽略的是空状态处理——比如智能指针为 nullptr 时,* 和 -> 都应抛异常或断言,而不是静默返回垃圾值。C++ 不强制要求检查,但生产代码里漏掉这个,崩溃只在运行时找上门。


















