Назад | Начало урока | Вперед
Содержание

Глава 8

Вверх

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


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

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

//Listing 9.11 // Passing pointers to objects


#include <iostream>
using namespace std;

class SimpleCat {

public:
SimpleCat();
SimpleCat(SimpleCat&);
~SimpleCat();

int GetAge() 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 FunctionTwo (const SimpleCat * const theCat);

int main() {


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


cout << "Frisky is " ;
cout << Frisky.GetAge();
cout << " years old\n";

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

cout << "Calling FunctionTwo...\n";
FunctionTwo(&Frisky);

cout << "Frisky is " ;
cout << Frisky.GetAge();
cout << " years old\n";
return 0;

}

// functionTwo, passes a const pointer

const SimpleCat * const FunctionTwo
(const SimpleCat * const theCat) {


cout << "Function Two. Returning...\n";
cout << "Frisky is now " << theCat->GetAge();
cout << " years old \n";
// theCat->SetAge(8); const!
return theCat;
}

Результат:

1.Making a cat...
2.Simple Cat Constructor...

3.Frisky is 1 years old
4.Frisky is 5 years old

5.Calling FunctionTwo...
6.Function Two. Returning...
7.Frisky is now 5 years old

8.Frisky is 5 years old
9.Simple Cat Destructor...

Анализ:

Как видим в класс добавлена постоянная функция GetAge()

int GetAge() const {

return itsAge;
}

и функция которая не является постоянной SetAge().

void SetAge(int age) {

itsAge = age;
}

Так же добавлена переменная-член itsAge.

private:
int itsAge;

Конструктор, конструктор копий и деструктор по прежнему выводят на экран свои сообщения. Конструктор копий ни разу не вызывался поскольку объект был передан как ссылка.

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

SimpleCat Frisky;

cout << "Frisky is " ;
cout << Frisky.GetAge();
cout << " years old\n";

Вот как вывел компьютер на экран результат этих инструкций

1.Making a cat... 2.Simple Cat Constructor...
3.Frisky is 1 years old

Далее переменной itsAge присваивается новое значение и с помощью функции SetAge() происходит изменение этого значения внутри класса у закрытого члена.
Затем вызов функции чтобы убедиться что изменение закрытой переменной произошло.

int age = 5;
Frisky.SetAge(age);

cout << "Frisky is " ;
cout << Frisky.GetAge();
cout << " years old\n";

Смотри сообщение 4. Вот как вывел компьютер результат этих инструкций:

4.Frisky is 5 years old

В этой программе функция FunctionTwo() слегка изменена.Вот ее объявление

const SimpleCat * const FunctionTwo
(const SimpleCat * const theCat);

На этот раз и параметр и возвращаемое значение объявляются как постоянные указатели на постоянные объекты.

Вот инструкции этой функции:

cout << "Function Two. Returning...\n";
cout << "Frisky is now " << theCat->GetAge();
cout << " years old \n";

Вот как вывел компьютер на экран результат этих инструкций:

5.Calling FunctionTwo...
6.Function Two. Returning...
7.Frisky is now 5 years old

Поскольку и параметр и возвращаемое значение передаются как ссылки, (да еще через указатели!)ни какие копии не создаются и конструктор копий не вызывается.

Но указатель в функции теперь является постоянным, следовательно к нему не может применяться непостоянная функция SetAge(). Если бы обращение к функции SetAge() не было закомментировано, то программа не прошла бы этап компиляции.

// theCat->SetAge(8); const!

Обратите внимание что объект создаваемый в функции main() не является постоянным, и объект Frisky может вызвать функцию SetAge(). Адрес этого обычного объекта передается функции FunctionTwo() но поскольку в объявлении функции FunctionTwo() заявлено что передаваемый указатель должен быть постоянным указателем на постоянный объект , то с этим объектом функция обращается так, как если бы он был постоянным!.

И наконец последние инструкции из главной программы:

cout << "Frisky is " ;
cout << Frisky.GetAge();
cout << " years old\n";

Вот как вывел компьютер на экран результат этих инструкций:

8.Frisky is 5 years old

И наконец окончание функции main()
Комньютер выводит последнее сообщение:

9.Simple Cat Destructor...


Назад | Начало урока | Вверх | Вперед
Содержание

Hosted by uCoz