Как мне создать и использовать оператор стрелки класса? - PullRequest
23 голосов
/ 08 февраля 2011

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

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

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

Ответы [ 4 ]

28 голосов
/ 08 февраля 2011

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

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

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;
    }
};

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

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

Запустить онлайн: https://wandbox.org/permlink/Is5kPamEMUCA9nvE

Из Stroupstrup:

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

требуется имя члена
25 голосов
/ 08 февраля 2011

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

#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
0 голосов
/ 08 февраля 2011

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

a->b

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

return_type my_class::operator->()
0 голосов
/ 08 февраля 2011
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

...