重载运算符 ->
Posted
技术标签:
【中文标题】重载运算符 ->【英文标题】:Overloading operator -> 【发布时间】:2011-06-21 05:47:02 【问题描述】:这是我的代码示例:
class X
public:
void f()
;
class Y : public X
public:
X& operator->() return *this;
void f()
;
int main()
Y t;
t.operator->().f(); // OK
t->f(); // error C2819: type 'X' does not have an overloaded member 'operator ->'
// error C2232: '->Y::f' : left operand has 'class' type, use '.'
为什么编译器试图将 operator-> 的责任从 Y 转移到 X?当我实现 X::op-> 时,我不能在那里返回 X - 编译错误说“无限递归”,而从 X::op-> 返回一些 Z 再次表示 Z 没有 operator->,因此会更高并且层次更高。
谁能解释这个有趣的行为? :)
【问题讨论】:
【参考方案1】:问题在于operator ->
应该返回一个指针,而不是一个引用。这个想法是operator ->
应该返回一个指向应该应用指针的真实对象的指针。例如,对于具有重载 operator ->
的类,代码
myClass->myValue;
翻译成
(myClass.operator-> ())->myValue;
你的代码的问题是operator ->
返回一个引用,所以写
myClass.operator->().f();
是完全合法的,因为你明确地调用了操作符,但是写
myClass->f();
是非法的,因为编译器试图将其扩展为
myClass.operator->()->f();
operator->
的返回类型不是指针。
要解决此问题,请更改您的代码,以便在 operator ->
中返回一个指针。如果要重载运算符以返回引用,请重载operator *
;指针取消引用确实应该产生引用。
【讨论】:
我不会说它应该返回一个指针,只是它返回的任何东西都需要支持operator->
。
@GMan- 好点。我在这里是为了简单,但你是对的。有一些非常有趣的技巧,你可以使用依赖这种技术的智能指针来完成。
@GMan:既然这样的类型统称为智能指针,我认为templatetypedef用指针这个词并没有错,他只是在一般意义上使用它。
虽然不完全正确“问题是操作符 -> 应该返回一个指针,而不是一个引用。”一句话回答了我的问题。【参考方案2】:
因为这就是重载 ->
在 C++ 中的工作方式。
当您使用重载的->
时,表达式a->b
将转换为a.operator->()->b
。这意味着您的重载运算符->
必须返回一些本身支持运算符->
的另一个应用程序的内容。出于这个原因,重载->
的单个调用可能会变成一长串重载->
s 的调用,直到它最终到达内置->
的应用程序,从而结束该链。
在您的情况下,您需要从重载的 ->
中返回 X*
,而不是 X&
。
【讨论】:
【参考方案3】:语法错误,应该是:
T->T2
T2* T::operator ->();
看***的文章:Operators in C and C++
如果要重载,必须对重载的运算符使用正确的语法
【讨论】:
【参考方案4】:你可能想要:
class Y : public X
public:
X* operator->() return this;
void f()
;
【讨论】:
以上是关于重载运算符 ->的主要内容,如果未能解决你的问题,请参考以下文章