重载运算符 ->

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() 
;

【讨论】:

以上是关于重载运算符 ->的主要内容,如果未能解决你的问题,请参考以下文章