【问题标题】:clarification on overloading the -> operator关于重载 -> 运算符的说明
【发布时间】:2019-05-14 10:19:38
【问题描述】:

我试图了解重载 -> 运算符的工作原理。我有以下课程

class Message {

public:
    Message(string message) :m_text(message) {}
    void printText() {
        cout << "text is " << m_text << endl;
    }
    string m_text;
};


class MessagePointerWrapper
{
public:

    MessagePointerWrapper(string message)  {
        m_message = std::make_unique<Message>(message);
    }

    Message* operator->() {

        return m_message.get();
    }

    std::unique_ptr<Message> m_message;

};

int main(int argc, char** argv)
{

    MessagePointerWrapper messageWrapper =  MessagePointerWrapper("Hello World");
    messageWrapper.m_message->printText();
    messageWrapper->m_text = "PQR";
    messageWrapper.m_message->printText();
}

MessageWrapper 类的 -&gt; 运算符被重载以返回 Message*。 所以在我调用messageWrapper-&gt; 的主要方法中,它返回的是Message*。通常当我有一个指针的时候,我需要使用-&gt; 操作符或者deference 操作符来访问对象。 按照这个逻辑,要访问Message对象的m_text可验证,代码应该写如下

(messageWrapper->)   // this returns a pointer to Message. so to access the object, I should write as
(messageWrapper->)->m_text = "PQR"

*(messageWrapper->).m_Text = "PQR"

但这不起作用,我需要将其称为

messageWrapper->m_text = "PQR";

我不明白这里的逻辑。请让我澄清一下。

==============

一些进一步的说明:

在 main 方法中我看到下面两个方法做同样的事情

messageWrapper.operator->()->m_text = "JKH";

messageWrapper->m_text = "JKH";

这是否意味着运算符-&gt; 与其他运算符的工作方式不同

messageWrapper-&gt; 等价于(messageWrapper.operator-&gt;())-&gt; 而不是 messageWrapper.operator-&gt;() 就像其他运营商的情况。

【问题讨论】:

  • *(messageWrapper-&gt;).m_Text 语法错误。
  • 您能解释一下原因吗?这就是我不明白的。 (messageWrapper->) 是一个指向消息的指针。取消引用访问对象的指针应该是 (messageWrapper->)-> 或 *(messageWrapper->)
  • [overloading-member-access-operators-c][1] 的可能副本。 [1]:stackoverflow.com/questions/8777845/…

标签: c++ operator-overloading


【解决方案1】:

运算符 -> 必须返回一个指针,使用时返回值会自动取消引用,因此您不必自己添加第二个 ->

【讨论】:

    【解决方案2】:

    标准说:

    13.5.6 班级成员访问权限

    表达式x-&gt;m 被解释为类的(x.operator-&gt;())-&gt;m 对象x 类型为T 如果T::operator-&gt;() 存在并且操作符是 被重载决议选为最佳匹配函数 机制

    【讨论】:

      【解决方案3】:

      按照标准规定,[over.ref]/1

      如果T::operator-&gt;() 存在并且运算符被重载解析机制选择为最佳匹配函数,则表达式x-&gt;m 被解释为x 类型为T 的类对象(x.operator-&gt;())-&gt;m

      这意味着messageWrapper-&gt;m_text(messageWrapper.operator-&gt;())-&gt;m_text 的语法糖。您可以显式应用后一种样式,但前者更有效。重载的operator-&gt; 使得可以像使用原始指针一样使用类,这就是像std::unique_ptrstd::shared_ptr 这样的智能指针的工作原理。

      【讨论】:

        【解决方案4】:

        -> 是一个二元运算符,它同时使用两个参数,只要它不是指针,它就会继续解析左侧。

        也就是说,在调用 Wrapper2::operator ->() 之后的以下代码中,编译器看到返回类型是引用并调用 Wrapper1::operator ->,然后调用才会产生指针'm' 是针对 RealType 解析的。

        struct RealType
        {
            int m;
        };
        
        class Wrapper1 {
            RealType rt;
        
        public:
            RealType * operator ->() { return &rt; }
        };
        class Wrapper2 {
            Wrapper1 w1;
        
        public:
            Wrapper1 & operator->() { return w1; }
        };
        
        int main()
        {
            Wrapper2 w;
            w->m = 1;
        };
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-04-01
          • 2013-06-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-09-17
          • 1970-01-01
          相关资源
          最近更新 更多