How do I create and use a class arrow operator?

2020-02-07 19:27发布

问题:

So, after researching everywhere for it, I cannot seem to find how to create a class arrow operator, i.e.,

class Someclass
{
  operator-> ()  /* ? */
  {
  }
};

I just need to know how to work with it and use it appropriately. - what are its inputs? - what does it return? - how do I properly declare/prototype it?

回答1:

The operator -> is used to overload member access. A small example:

#include <iostream>
struct A 
{
    void foo() {std::cout << "Hi" << std::endl;}
};

struct B 
{
    A a;
    A* operator->() {
        return &a;
    }
};

int main() {
    B b;
    b->foo();
}

This outputs:

Hi


回答2:

The arrow operator has no inputs. Technically, it can return whatever you want, but it should return something that either is a pointer or can become a pointer through chained -> operators.

The -> operator automatically dereferences its return value before calling its argument using the built-in pointer dereference, not operator*, so you could have the following class:

class PointerToString
{
    string a;

public:
    class PtPtS
    {
    public:
        PtPtS(PointerToString &s) : r(s) {}
        string* operator->()
        {
            std::cout << "indirect arrow\n";
            return &*r;
        }
    private:
        PointerToString & r;
    };

    PointerToString(const string &s) : a(s) {}
    PtPtS operator->()
    {
        std::cout << "arrow dereference\n";
        return *this;
    }
    string &operator*()
    {
        std::cout << "dereference\n";
        return a;
    }
};

Use it like:

PointerToString ptr(string("hello"));
string::size_type size = ptr->size();

which is converted by the compiler into:

string::size_type size = (*ptr.operator->().operator->()).size();

(with as many .operator->() as necessary to return a real pointer) and should output

arrow dereference
indirect dereference
dereference

Note, however, that you can do the following:

PointerToString::PtPtS ptr2 = ptr.operator->();

run online: https://wandbox.org/permlink/Is5kPamEMUCA9nvE

From Stroupstrup:

The transformation of the object p into the pointer p.operator->() does not depend on the member m pointed to. That is the sense in which operator->() is a unary postfix operator. However, there is no new syntax introduced, so a member name is still required after the ->



回答3:

class T {
    public:
        const memberFunction() const;
};

// forward declaration
class DullSmartReference;

class DullSmartPointer {
    private:
        T *m_ptr;
    public:
        DullSmartPointer(T *rhs) : m_ptr(rhs) {};
        DullSmartReference operator*() const {
            return DullSmartReference(*m_ptr);
        }
        T *operator->() const {
            return m_ptr;
        }
};

http://en.wikibooks.org/wiki/C++_Programming/Operators/Operator_Overloading#Address_of.2C_Reference.2C_and_Pointer_operators



回答4:

The "arrow" operator can be overloaded by:

a->b

will be translated to

return_type my_class::operator->()