Оператор стрелки не имеет входов. Технически, он может возвращать все, что вы хотите, но он должен возвращать то, что либо является указателем, либо может стать указателем через операторы ->
в цепочке .
Оператор ->
автоматически разыменовывает свое возвращаемое значение перед вызовом аргумента , используя разыменование встроенного указателя, а не 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->()
является унарным постфиксным оператором. Однако новый синтаксис не введен, поэтому после ->
требуется имя члена