Правила программирования на Си и Си++



         

121. Никогда не используйте ссылки в качестве результатов, пользуйтесь указателями - часть 3


используют указатели на то место, где будут храниться результаты. Я затем преобразую те аргументы, которые передаются по значению, в ссылки на константные объекты, если эти аргументы:

·      являются объектами какого-то класса (в отличие от основных типов, подобных int);

·      не модифицируются где-то внутри функции.

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

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

содержит список объектов CView. Вы можете получить доступ к элементам этого списка следующим образом:

CDocument  *doc;

CView      *view;

POSITION pos = doc->GetFirstViewPosition();

while(  view = GetNextView(pos) )

   view->Invalidate();

Здесь есть две проблемы. Во-первых, у функции GetNextView()

неудачное имя. Она должна быть названа GetCurrentViewAndAdvancePosition(), потому что она на самом деле возвращает текущий элемент и затем продвигает указатель положения (который является ссылочным аргументом результата) на следующий элемент. Что приводит нас ко второй проблеме: средний читатель смотрит на предыдущий код и задумывается над тем, как завершается этот цикл. Другими словами, здесь скрывается сюрприз. Операция итерации цикла скрыта в GetNextView(pos), поэтому неясно, где она происходит. Ситуация могла быть хуже, если бы цикл был больше и содержал бы несколько функций, использующих pos в качестве аргумента — вы бы не имели никакого представления о том, какая из них вызывает перемещение.

Есть множество лучших способов решения этой проблемы. Простейший заключается в использовании в качестве аргумента GetNextView()

указателя вместо ссылки:

POSITION pos = doc->GetFirstViewPosition();

while( p = GetNextView( &pos ) )

   p->Invalidate();

Таким способом &pos

сообщает вам, что pos

будет модифицироваться; иначе зачем передавать указатель? Тем не менее, существуют и лучшие решения. Вот первое:




Содержание  Назад  Вперед