Выбрать главу

[Советы] 

►Почему ссылки не используются вместо указателей...175

Синтаксис работы со ссылками аналогичен синтаксису, используемому при работе с обычными объектами. Так почему бы не перейти на использование только ссылок и никогда не использовать указатели?

_________________

175 стр. Глава 14. Указатели на объекты

Объекты и их адреса — это "две большие разницы", и зачастую синтаксис для ссылок оказывается более сложным, чем синтаксис при работе с указателями. Рассмотрим следующий пример.

    class Student

    {

      public :

        int semesterHours ;

        float gpa ;

        Student valFriend ;

        Student& refFriend ;

        Student* ptrFriend ;

    } ;

    int main( int nNumberOfArgs , char* pszArgs[ ] )

    {

        /* Ссылка на объект в куче */

        Student& student = *new Student ;

        student.gpa = 10 ;

        // To же

        Student& studentFriend = *new Student ;

        studentFriend.gpa = 20 ;

        /* Копирование значения одного объекта типа Student в другой */

        student.valFriend = studentFriend ;

        /* Этот код не будет работать */

        Student& refFriend ;

        refFriend = studentFriend ;

        /* Этот код корректен */

        student.ptrFriend = &studentFriend ;

        return 0 ;

    }

Как видите, я модифицировал класс Student так, чтобы он мог указать своего лучшего друга[ 14 ]. Для этого я пытаюсь воспользоваться ссылочной переменной. В функции main( ) я создаю двух студентов и пытаюсь сделать одного из них другом другого.

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

►Использование связанных списков...176

Связанный список является второй по распространённости структурой после массива. Каждый объект в связанном списке указывает на следующий, образуя цепочку в памяти.

___________

14Это сделано некорректно; как минимум член valFriend не может быть определён в классе того же типа, не считая массы других ошибок. Поэтому к данному примеру следует относиться как к не более чем поясняющей сугубо теоретической модели, которая никогда не будет даже скомпилирована. — Прим. ред.

_________________

176 стр. Часть 3. Введение в классы

К связанному списку легко добавить ещё один элемент — путём изменения указателя в последнем объекте списка. В этом заключается основное преимущество связанного списка — отсутствие необходимости задавать фиксированный размер на этапе компиляции: связанный список может уменьшаться и увеличиваться в зависимости от потребностей программы. Цена этой гибкости — скорость работы со списком, поскольку обратиться к какому-то из элементов списка можно, только пройдя по всем предыдущим.

Не всякий класс может быть использован для создания связанного списка. Связываемый класс объявляется так, как показано в приведённом ниже фрагменте.

    class LinkableClass

    {

        public :

            LinkableClass* pNext ;

            /* Прочие члены класса */

    } ;

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

Указатель pNext и есть тот элемент, с помощью которого дети объединяются в цепочки. Фигурально выражаясь, можно сказать, что список детей состоит из некоторого количества объектов, каждый из которых имеет тип "ребёнок". Каждый ребёнок указывает на следующего ребенка.

вернуться

14

Это сделано некорректно; как минимум член valFriend не может быть определён в классе того же типа, не считая массы других ошибок. Поэтому к данному примеру следует относиться как к не более чем поясняющей сугубо теоретической модели, которая никогда не будет даже скомпилирована.