有关重载->运算符的说明

时间:2018-12-13 08:31:16

标签: c++ operator-overloading

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

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类的->运算符被重载以返回Message*。 因此,在主方法中,当我调用messageWrapper->时,它返回的是Message*。通常,当我有一个指针时,我需要使用->运算符或deference运算符来访问该对象。 根据该逻辑,要访问m_text对象的Message验证,代码应如下编写

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

我不明白这里的逻辑。我可以对此进行澄清。

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

一些其他说明:

在主要方法中,我看到以下两种方法具有相同的作用

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

messageWrapper->m_text = "JKH";

这是否意味着运营商->的工作方式不同于其他运营商

messageWrapper->等效于(messageWrapper.operator->())-> 而不是messageWrapper.operator->(),就像其他运算符一样。

4 个答案:

答案 0 :(得分:9)

标准状态为[over.ref]/1

  

如果类型为{{1}的类对象x->m(如果存在(x.operator->())->m并且如果选择了最佳运算符,则表达式x被解释为T通过重载解析机制实现匹配功能

这意味着T::operator->()messageWrapper->m_text的语法糖。您可以显式地应用后一种样式,但是前一种样式更有效。重载的(messageWrapper.operator->())->m_text使得可以像原始指针一样使用该类,这就是operator->std::unique_ptr这样的智能指针的工作方式。

答案 1 :(得分:5)

标准说:

  

13.5.6类成员访问权限

     

表达式x->m被解释为类的(x.operator->())->m   类型x的对象T(如果存在T::operator->()并且操作符为   过载分辨率选择为最佳匹配函数   机制

答案 2 :(得分:3)

->是二进制运算符,它同时使用两个参数,并且只要不是指针,都将继续解析左侧。

也就是说,在下面的代码中,在调用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;
};

答案 3 :(得分:2)

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