Как создать и использовать оператор со стрелкой класса?
Итак, после исследования повсюду для него, я не могу найти, как создать оператор стрелки класса, т.е.
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->()
является унарным постфиксным оператором. Однако новый синтаксис не вводится, поэтому после ->
по-прежнему требуется имя участника,
Ответ 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
Оператор "стрелка" может быть перегружен:
a->b
будет переведен на
return_type my_class::operator->()