【问题标题】: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->,因此会更高并且层次更高。

谁能解释这个有趣的行为? :)

【问题讨论】:

    标签: c++ overloading operator-keyword


    【解决方案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() {}
        };
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-02-19
          • 1970-01-01
          • 2012-09-14
          • 2011-04-08
          • 2012-03-10
          • 2011-08-06
          相关资源
          最近更新 更多