Читаем Освой самостоятельно С++ за 21 день. полностью

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

Ссылки в качестве альтернативы

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

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

Листинг 3.12. Передача ссылок на объекты

1: // Листинг 9.12.

2: // Передача ссылок на объекты

3:

4: #include

5:

6: class SimpleCat

7: {

8:    public:

9:       SimpleCat;

10:      SimpleCat(SimpleCat&);

11:      ~SimpleCat;

12:

13:   int GetAge const { return itsAge; }

14:   void SetAge(int age) { itsAge = age: }

15:

16:   private:

17:      int itsAge;

18: };

19:

20: SimpleCat::SimpleCat

21: {

22:    cout << "Simple Cat Constructor...\n";

23:    itsAge = 1;

24: }

25:

26: SimpleCat::SimpleCat(SimploCat&)

27: {

28:    cout << "Simple Cat Copy Cunstructor...\n";

29: }

30:

31: SimpleCat::~SimpleCat

32: {

33:    cout << "Simple Cat Destructor...\n";

34: }

35:

36: const SimpleCat & FunctionTwo (const SimpleCat & theCat);

37:

38: int main

39: {

40:    cout << "Making a cat...\n";

41:    SimpleCat Frisky;

42:    cout << "Frisky is " << Frisky.GetAge << " years old\n";

43:    int age = 5;

44:    Frisky,SetAge(age);

45:    cout << "Frisky is " << Frisky.GetAge << " years old\n";

46:    cout << "Calling FunctionTwo...\n";

47:    FunctionTwo(Frisky);

48:    cout << "Frisky is " << Frisky.GetAge << " years old\n";

49:    return 0;

50: }

51:

52: // functionTwo, passes a ref to a const object

53: const SimpleCat & FunctionTwo (const SimpleCat & theCat)

54: {

55:    cout << "Function Two. Returning...\n";

56:    cout << "Frisky is now " << theCat.GetAge;

57:    cout << " years old \n";

58:    // theCat.SetAge(8); const!

59:    return theCat;

60: }


Результат:

Making a cat...

Simple Cat constructor...

Frisky is 1 years old

Frisky is 5 years old

Calling FunctionTwo...

FunctionTwo. Returning...

Frisky is now 5 years old

Frisky is 5 years old

Simple Cat Destructor...


Анализ: Результат работы этой программы идентичен результату, показанному после листинга9.11. Единственное существенное изменение — функция FunctionTwo теперь принимает и возвращает ссылки на константный объект. И вновь-таки работа со ссылками несколько проще, чем работа с указателями, хотя при этом достигается та же экономия средств и эффективность выполнения, а также обеспечивается надежность за счет использования спецификатора const.


Константные ссылки

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

Когда лучше использовать ссылки, а когда - указатели

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

Но ссылки нельзя переназначать. Если же вам нужно сначала указывать на один объект, а затем на другой, придется использовать указатель. Ссылки не могут быть нулевыми, поэтому, если существует хоть какая-нибудь вероятность того, что рассматриваемый объект может быть нулевым, вам нельзя использовать ссылку. В этом случае необходимо использовать указатель.

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

Перейти на страницу:

Похожие книги

Сущность технологии СОМ. Библиотека программиста
Сущность технологии СОМ. Библиотека программиста

В этой книге СОМ исследуется с точки зрения разработчика C++. Написанная ведущим специалистом по модели компонентных объектов СОМ, она раскрывает сущность СОМ, помогая разработчикам правильно понять не только методы модели программирования СОМ, но и ее основу. Понимание мотивов создания СОМ и ее аспектов, касающихся распределенных систем, чрезвычайно важно для тех разработчиков, которые желают пойти дальше простейших приложений СОМ и стать по-настоящему эффективными СОМ-программистами. Показывая, почему СОМ для распределенных систем (Distributed СОМ) работает именно так, а не иначе, Дон Бокс дает вам возможность применять эту модель творчески и эффективно для ежедневных задач программирования.

Дональд Бокс

Программирование, программы, базы данных / Программирование / Книги по IT