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

            system( "PAUSE" ) ; return 0 ;

    }

 

    Значение s.gpa = 0

    Вызов someFn( Student& )

    Значение refS.gpa = 3

    Возврат из someFn( Student& )

    Значение s.gpa = 3

    Press any key to continue...

В этой программе в функцию someFn( ) передаётся не копия объекта, а ссылка на него. Изменения, внесённые функцией someFn( ) в s, сохраняются внутри main( ).

 

«Передача объекта по ссылке — всего лишь другой способ передачи в функцию адреса объекта s. С++ самостоятельно отслеживает адрес ссылки, в то время как при передаче указателя вы должны заниматься этим сами.» 

[Советы]

►Зачем, использовать указатели и ссылки...174

Итак, передать объект в функцию можно разными способами. Но почему бы нам не ограничиться одним, простейшим способом — передачей по значению?

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

А вот и вторая причина — некоторые объекты могут оказаться действительно очень большими. Передача такого объекта по значению приводит к копированию большого объёма информации в память функции.

«Область, используемая для передачи аргументов функции, называется стеком вызова.»

[Технические подробности]

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

«Проблема на самом деле ещё сложнее, чем описано здесь. В главе 18, "Копирующий конструктор", вы убедитесь, что создание копии объекта представляет собой существенно более сложную задачу, чем простое копирование участка памяти из одного места в другое.»

[Атас!]

_________________

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

►Возврат к куче...175

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

    MyClass* myFunc( )

    {

        /* Эта функция не будет работать правильно */

        MyClass mc ;

        MyClass* рМС = &mc ;

        return рМС ;

    }

После возврата из myFunc( ) объект mc выходит из области видимости, а значит, указатель, который возвращает myFunc( ), указывает на несуществующий объект.

«Проблемы, связанные с возвратом памяти, которая выходит из области видимости, рассматривались в главе 9, "Второе знакомство с указателями"

[Помни!]

Использование кучи позволяет решить эту проблему:

    MyClass* myFunc( )

    {

        MyClass* рМС = new MyClass ;

        return рМС ;

    }

«С помощью кучи можно выделять память для объектов в самых разнообразных ситуациях.»

[Помни!] 

►Сравнение указателей и ссылок...175

Очень часто новички в программировании спрашивают, зачем нужны и указатели, и ссылки, и нельзя ли обойтись чем-то одним?

«В принципе, можно обойтись чем-то одним. Тот же С#, да и многие другие языки обходятся без указателей. Однако С++ — язык крайне широкого применения, и имеется множество задач, решение которых существенно упрощается при использовании указателей. Указатели — неотъемлемая часть стандартного, не ограниченного узкими рамками Visual Studio .NET языка программирования С++.»