Как создать и использовать оператор со стрелкой класса?

Итак, после исследования повсюду для него, я не могу найти, как создать оператор стрелки класса, т.е.

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

Мне просто нужно знать, как работать с ним и использовать его соответствующим образом. - Каковы его вклад? - Что он возвращает? - Как правильно объявить/прототип?

Ответ 1

Оператор → используется для перегрузки доступа к члену. Небольшой пример:

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

Выводится:

Hi

Ответ 2

Оператор стрелки не имеет входов. Технически он может возвращать все, что угодно, но должен возвращать то, что либо является указателем, либо может стать указателем через цепочку -> операторов.

Оператор -> автоматически разыскивает свое возвращаемое значение перед вызовом его аргумента с помощью встроенного разворота указателя, а не operator*, поэтому вы можете иметь следующий класс:

class PointerToString
{
    string a;

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

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

Используйте его как:

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

который преобразуется компилятором в:

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

(с большим количеством .operator->() при необходимости для возврата реального указателя) и должен выводить

arrow dereference
indirect dereference
dereference

Обратите внимание, однако, что вы можете сделать следующее:

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

От Stroupstrup:

Преобразование объекта p в указатель p.operator->() не зависит от элемента m, на который указывает. В этом смысл, в котором operator->() является унарным постфиксным оператором. Однако новый синтаксис не вводится, поэтому после ->

по-прежнему требуется имя участника,

Ответ 4

Оператор "стрелка" может быть перегружен:

a->b

будет переведен на

return_type my_class::operator->()