Программирование >>  Дополнительные возможности наследования 

1 ... 74 75 76 [ 77 ] 78 79 80 ... 265


33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55

cout Making я oat ,\ n ; SimpleCat Frisky; CQUt Calling FunctlonOno. FunctionOne(Frisky); cout << Calling FundionTwo. FunctlonTwo(&Frlsky); return 0;

Л n ; Л n ;

Фугнкция FunctionOne, порадача как значония SimpleCat FunctionOno(Slmp]eCat tliaCat) {

cout << Function One. Roturnlng...\ n return theCat;

Функция FundionTwo, передача как ссылки SimpleCat* FunctlonTwo (SimpleCat *theCat) {

cout << Function Two. Returning ,\ n return ttieCat;

Making a cat... Simple Cat Constructor. Calling FunctionOne.., Simple Cat Copy Constructor , Function One. Returning , Simple Cat Copy Constructor... Simple Cat Destructor... Simple Cat Destructor,.. Calling FunctlonTwo,., Function Two. Returning... Simple Cat Destructor...

(ШЛЕЧАНИЕ

Номера строк не выводятся. Мы добавили их для удобства проведения анализа программы.

В строках 6-12 объявляется весьма упрощенный класс SimpleCat. Конструктор, конструктор-копировщик и деструктор - все компоненты класса

выводят на экран свои информативные сообщения, чтобы было точно известно, когда

они вызываются,

В строке 34 функция main() выводит свое первое сообщение, которое является первым и в результатах работы программы, В строке 35 создается экземпляр объекта класса SimpleCat. Это приводит к вызову конструктора, что подтверждает сообщение, выводимое этим конструктором (строка 2 в результатах работы программы).



в строке 36 функция main() докладывает о вызове функции FunctionOne, которая выводит свое сообщение (строка 3 в результатах работы профаммы). Поскольку функция FunctionOneO вызывается с передачей объекта класса SimpleCat по значению, в стек помещается копия объекта SimpleCat как локального для вызываемой функции. Это приводит к вызову конструктора копии, который вносит свою лепту в результаты работы профаммы (сообщение в строке 4).

Выполнение профаммы переходит к строке 46, которая принадлежит телу вызванной функции, выводящей свое информативное сообщение (строка 5 в результатах работы профаммы). Затем эта функция возвращает управление профаммой вызывающей функции, и объект класса SimpleCat вновь возвращается как значение. При этом создается еще одна копия объекта за счет вызова конструктора-копировщика и, как следствие, на экран выводится очередное сообщение (сфока 6 в результатах работы профаммы).

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

Управление профаммой возвращается к функции main(), после чего вызывается функция FunctionTwoO, но на этот раз парамеф передается как ссылка. При этом никакой копии объекта не создается, поэтому отсутствует и сообщение от конструктора-копировщика. В функции FunctionTwoO выводится сообщение, занимающее строку 10 в результатах работы профаммы, а затем выполняется возвращение объекта класса SimpleCat (снова как ссылки), поэтому нет никаких обращений к консфуктору и десфуктору.

Наконец профамма завершается и объект Frisky выходит за область видимости, генерируя последнее обращение к десфуктору, выводящему свое сообщение (строка 11 в результатах работы профаммы).

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

Передача константного дказателя

Несмотря на то что передача указателя функции FunctionTwoO более эффективна, чем передача по значению, она таит в себе немалую опасность. При вызове функции FunctionTwoO совершенно не имелось в виду, что разрешается изменять передаваемый ей объект класса SimpleCat, задаваемый в виде адреса объекта SimpleCat. Такой способ передачи открывает объект для изменений и аннулирует защиту, обеспечиваемую при передаче объекта как значения.

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

Решить проблему можно, передав в функцию указатель на константный объект класса SimpleCat. В этом случае к данному объекту могут применяться только константные методы, не имеющие прав на изменение объекта SimpleCat. Эта идея демонстрируется в листинге 9.11.



Листинг 8.11. Передача константных дказатедей

44 45 46 47

Листинг 9.11.

Передача константных указателей на обьекты

ftinclude <iostream.h>

class SimpleCat {

public:

SimpleCatO; SimpleCat(SimpleCat&); SimpleCatO;

int GetAgeO const { return itsAge; } void SetAge(int age) { itsAge = age; }

private:

int ItsAge;

SimpleCat::SimpleCat() {

cout Simple Cat Constructor...\n ; itsAge = 1;

SimpleCat::SimpleCat(SimpleCat&) {

cout Simple Cat Copy Constructor...\n ;

SimpleCat:: SimpleCat() {

cout Simple Cat Destructor...\n ;

const SimpleCat * const FunctlonTwo (const SimpleCat ♦ const theCai);

int mainO {

cout Making a cat...\ n ; SimpleCat Frisky; cout << Frisky is ;

43 cout << Frisky. GetAgeO ;

cout << years old\ n ; int age = 5; Frisky.SetAge(age); cout << Frisky is ; cout Frisky,GetAgeO;



1 ... 74 75 76 [ 77 ] 78 79 80 ... 265

© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика