C++模板类重载成员访问运算符->并按引用返回的实现问题
C++模板类重载->运算符实现方案
C++ 语言标准对 operator-> 有强制的语法约束:它的返回值必须是指针类型,或者是另一个重载了 operator-> 的类类型,不能直接返回引用,这是你代码编译失败的根本原因。
你代码中的错误点
- 模板类
Ref<T>内部重载operator->时重复定义了模板参数template <class T>,会遮蔽外层类的模板参数,属于基础语法错误。 - 尝试让
operator->返回T&类型,不符合operator->的返回值要求,编译器无法识别这个重载,就会报你遇到的「未定义该运算符」的错误。
正确实现方案
你的按引用返回对象的需求完全可以实现,只需要同时重载解引用运算符 operator* 和成员访问运算符 operator-> 即可:
operator*可以按引用返回内部包装的对象,满足你要引用返回的业务需求operator->按标准要求返回内部指针,支持ref->do_something()这种常用写法,不需要每次调用get()方法
完整可运行代码
#include <iostream> using namespace std; class A { public: void do_something() { cout << "Hey there"; } }; template<class T> class Ref { public: Ref(T* ptr) : objPtr(ptr) {} T& get() { return *objPtr; } // 重载解引用运算符,按引用返回对象,符合业务要求 T& operator*() const { return *objPtr; } // 重载->运算符,符合C++语法要求,支持直接成员访问 T* operator->() const { return objPtr; } private: T* objPtr; }; int main() { A myObj; Ref<A> ref(&myObj); // 两种调用方式都可以正常运行 ref->do_something(); (*ref).do_something(); // 需要按引用传递时直接取*ref即可,就是T&类型 // void some_func(T& arg); // some_func(*ref); return 0; }
补充说明
你之前参考的示例里所谓的「按引用返回」,其实是 operator* 的行为,和 operator-> 无关。operator-> 的返回值规则是语言层面定死的,不存在绕开的可能,上面的实现已经覆盖了你所有的需求。
内容的提问来源于stack exchange,提问作者Gregor Sattel
相关产品推荐
相关产品推荐

