Вход/Регистрация
Программирование. Принципы и практика использования C++ Исправленное издание
вернуться

Страуструп Бьерн

Шрифт:

if (p–>prev) p–>prev–>succ = n;

n–>prev = p–>prev; // предшественник p становится

// предшественником n

p–>prev = n; // n становится предшественником p

return n;

}

Как получить указатель на объект, для которого была вызвана функция

Link::insert
? Без помощи языка это сделать невозможно. Однако в каждой функции-члене существует идентификатор
this
, являющийся указателем на объект, для которого она вызывается. A в качестве альтернативы мы могли бы просто писать
this
вместо
p
.

Link* Link::insert(Link* n) // вставляет n перед p; возвращает n

{

if (n==0) return this;

if (this==0) return n;

n–>succ = this; // этот объект следует за n

if (this–>prev) this–>prev–>succ = n;

n–>prev = this–>prev; // предшественник этого объекта

// становится

// предшественником объекта n

this–>prev = n; // n становится предшественником этого

// объекта

return n;

}

Это объяснение выглядит немного многословным, но мы не обязаны упоминать, что указатель

this
обеспечивает доступ к члену класса, поэтому код можно сократить.

Link* Link::insert(Link* n) // вставляет n перед p; возвращает n

{

if (n==0) return this;

if (this==0) return n;

n–>succ = this; // этот объект следует за n

if (prev) prev–>succ = n;

n–>prev = prev; // предшественник этого объекта

// становится

// предшественником объекта n

prev = n; // n становится предшественником этого

// объекта

return n;

}

Иначе говоря, при каждом обращении к члену класса происходит неявное обращение к указателю

this
. Единственная ситуация, в которой его необходимо упомянуть явно, возникает, когда нужно сослаться на весь объект.

Обратите внимание на то, что указатель

this
имеет специфический смысл: он ссылается на объект, для которого вызывается функция-член. Он не указывает на какой-то из ранее использованных объектов. Компилятор гарантирует, что мы не сможем изменить значение указателя
this
в функции-члене. Рассмотрим пример.

struct S {

// ...

void mutate(S* p)

{

this = p; // ошибка: указатель this не допускает изменений

// ...

}

};

17.10.1. Еще раз об использовании списков

Сталкиваясь с вопросами реализации, мы можем увидеть, как выглядит использование списка.

Link* norse_gods = new Link("Thor");

norse_gods = norse_gods–>insert(new Link("Odin"));

norse_gods = norse_gods–>insert(new Link("Zeus"));

norse_gods = norse_gods–>insert(new Link("Freia"));

Link* greek_gods = new Link("Hera");

greek_gods = greek_gods–>insert(new Link("Athena"));

greek_gods = greek_gods–>insert(new Link("Mars"));

greek_gods = greek_gods–>insert(new Link("Poseidon"));

Это очень похоже на предыдущие фрагменты нашей программы. Как и раньше, исправим наши ошибки. Например, укажем правильное имя бога войны.

Link* p = greek_gods–>find("Mars");

if (p) p–>value = "Ares";

Перенесем Зевса в список греческих богов.

Link* p2 = norse_gods–>find("Zeus");

if (p2) {

if (p2==norse_gods) norse_gods = p2–>next;

p2–>erase;

greek_gods = greek_gods–>insert(p2);

}

И наконец, выведем список на печать.

  • Читать дальше
  • 1
  • ...
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: