Почему перегрузка оператора -> () полезна? - PullRequest
2 голосов
/ 08 марта 2011

Я видел следующий пример в книге языка программирования C ++

class Ptr {
     X* operator->( );
};

 voide f(Ptr p)
 {
   p->m=7;
   X* q1 = p->;
   X* q2 = p.operator->();
 }

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

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

Спасибо.

Ответы [ 4 ]

5 голосов
/ 08 марта 2011

Этот оператор перегружен при реализации объектов, которые ведут себя как (притворяются) указателями.

Хорошим примером будет boost::shared_ptr, который является классическим указателем подсчета ссылок, который автоматически удаляет указанный объект, когда все указатели уничтожены. Бесчисленные другие подобные объекты «умного указателя» были реализованы людьми по разным причинам.

(и, как указывалось, итераторы stl также используют это, чтобы вести себя как указатели, допуская синтаксис вроде it->method(); или it->data;)

3 голосов
/ 08 марта 2011
  1. Этот дизайн чрезвычайно полезен, когда мы хотим создать класс, который ведет себя как указатель; это случай интеллектуальных указателей (объекты, имеющие интерфейс, похожий на указатель, но предоставляющие дополнительные «услуги», например, автоматическое освобождение при уничтожении, передаче права собственности, подсчете ссылок, ...).

    Обратите внимание, что этот тип объекта также часто перегружает оператор * (разыменование), чтобы более точно имитировать указатели.

  2. Автор хочет сказать, что когда вы используете оператор -> для Ptr, это не имеет значения (в отношении operator->) того, что вы ставите после него: в любом случае, * Будет вызван метод 1015 *, который вернет указатель на объект, который будет рассматриваться для остальной части выражения.

<ч />

Чтобы сделать это более ясным: цитируем прямо из стандарта:

13.5.6 Доступ к ученикам

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

postfix-expression -> id-expression

Выражение x->m интерпретируется как (x.operator->())->m для объекта класса x типа T, если существует T::operator->() и если оператор выбран в качестве функции наилучшего соответствия с помощью механизма разрешения перегрузки (13.3) .

Другими словами:

  • если вы вызовете operator->() напрямую (второй и третий пример в коде OP), вы получите указатель, возвращенный методом operator->, как и в случае с любым методом;
  • если вы поместите вещи после оператора -> (например, x->m, как в первом примере в коде OP), будет вызван перегруженный operator->, и возвращенный указатель будет использоваться, как если бы ->m использовалось поверх него.
2 голосов
/ 28 сентября 2011

итераторы ... фундаментальная часть C++ standard library.

std::list<std::string> list_of_string
std::list<std::string>::iterator i;
for(i = list_of_string.begin(); i != list_of_string.end(); ++i)
{
  //WHERE -> IS OVERLOADED...
  printf("%s\n", i->c_str()); //print to the screen, printf() is C and requires a C-string.
}

обычно i следует рассматривать как std::list<> объект, а не std::string. Обычно c_str() также будет недоступен без - - перегружен.

1 голос
/ 08 марта 2011

позволяет создавать умные указатели.(маленькие объекты, которые ведут себя как обычные указатели)

Основной причиной этого является автоматическое управление памятью.Но также может быть использован для таких вещей, как прокси

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...