Чтение онлайн

на главную - закладки

Жанры

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

Либерти Джесс

Шрифт:

Работа с переменными-членами, которые хранят свои значения в области динамической памяти, рассматривалась ранее при обсуждении использования конструктора- копировщика (см. также рис. 10.1 и 10.2).

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

в другую. Различия между этими методами копирования показаны на рис. 10.3.

Все вышесказанное справедливо для присвоения данных. В случае использования оператора присваивания, процесс обмена данных протекает с некоторыми особенностями. Так, объект catTwo уже существует вместе со своими переменными, для каждой из которых выделены определенные ячейки памяти. В случае присвоения объекту новых значений предварительно необходимо освободить эти ячейки памяти. Что произойдет, если выполнить присвоение объекта catTwo самому себе:

catTwo = catTwo

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

Если не предусмотреть поддержку такой ситуации, то оператор присваивания сначала очистит ячейки памяти объекта catTwo, а затем попытается присвоить объекту catTwo свои собственные значения, которых уже не будет и в помине.

Чтобы предупредить подобную ситуацию, ваш оператор присваивания прежде всего должен определить, не совпадают ли друг с другом объекты по обе стороны от оператора присваивания. Это можно осуществить с помощью указателя this, как показано в листинге 10.15.

Листинг 10.15. Оператор присваивания

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

2: // Конструктор-копировщик

3:

4: #include <iostream.h>

5:

6: class CAT

7: {

8: public:

9: CAT; // конструктор по умолчанию

10: // конструктор-копировщик и деструктор пропущены!

11: int GetAge const { return *itsAge; }

12: int GetWeight const { return *itsWeight; }

13: void SetAge(int age) { *itsAge = age; }

14: CAT & operator=(const CAT &);

15:

16: private:

17: int *itsAge;

18: int *itsWeight;

19: };

20:

21: CAT::CAT

22: {

23: itsAge = new int;

24: itsWeight = new int;

25: *itsAge = 5;

26: *itsWeight = 9;

27: }

28:

29:

30: CAT & CAT::operator=(const CAT & rhs)

31: {

32: if (this == &rhs)

33: return *this;

34: *itsAge = rhs.GetAge;

35: *itsWeight = rhs.GetWeight;

36: return *this;

37: }

38:

39:

40: int main

41: {

42: CAT frisky;

43: cout << "frisky's age: " << frisky.GetAge << endl;

44: cout << "Setting frisky to 6...\n";

45: frisky.SetAge(6);

46: CAT whiskers;

47: cout << "whiskers' age: " << whiskers.GetAge << endl;

48: cout << "copying frisky to whiskers...\n";

49: whiskers = frisky;

50: cout << "whiskers' age: " << whiskers.GetAge << endl;

51: return 0;

52: }

Результат:

frisky's age: 5

Setting frisky to 6. . .

whiskers' age: 5

copying frisky to whiskers...

whiskers' age: 6

Анализ:

В листинге 10.15 вновь используется класс CAT. Чтобы не повторяться, в данном коде пропущены объявления конструктора-копировщика и деструктора. В строке 14 объявляется оператор присваивания, определение которого представлено в строках 30—37.

В строке 32 выполняется проверка того, не является ли объект, которому будет присвоено значение, тем же самым объектом класса CAT, чье значение будет присвоено. Чтобы проверить это, сравниваются адреса в указателях rhs и this.

Безусловно, оператор присваивания (=) может быть произвольно перегружен таким образом, чтобы отвечать представлениям программиста, что означает равенство объектов.

Операторы преобразований

Что происходит при попытке присвоить значение переменой одного из базовых типов, таких как int или unsigned short, объекту класса, объявленного пользователем? В листинге 10.16 мы опять вернемся к классу Counter и попытаемся присвоить объекту этого класса значение переменной типа int.

Предупреждение:Листинг 10.16 не компилируйте!

Листинг 10.16. Попытка присвоить объекту класса Counter значение переменной типа int

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

2: // Эту программу не компилируйте!

3:

4: int

5: #include <iostream.h>

6:

7: class Counter

8: {

9: public:

10: Counter;

11: ~Counter{ }

12: int GetItsValconst { return itsVal; }

13: void SetItsVal(int x) { itsVal = x; }

14: private:

15: int itsVal;

16:

17: };

18:

19: Counter::Counter:

20: itsVal(0)

21: { }

22:

23: int main

24: {

25: int theShort = 5;

26; Counter theCtr = theShort;

27: cout << "theCtr: " << theCtr.GetItsVal << endl;

28: return 0;

29: }

Результат:

Компилятор покажет сообщение об ошибке, поскольку не сможет преобразовать тип int в Counter.

Поделиться:
Популярные книги

Мастер 9

Чащин Валерий
9. Мастер
Фантастика:
боевая фантастика
попаданцы
технофэнтези
аниме
фэнтези
5.00
рейтинг книги
Мастер 9

Сводный гад

Рам Янка
2. Самбисты
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Сводный гад

В погоне за женой, или Как укротить попаданку

Орлова Алёна
Фантастика:
фэнтези
6.62
рейтинг книги
В погоне за женой, или Как укротить попаданку

Возвышение Меркурия. Книга 16

Кронос Александр
16. Меркурий
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 16

Чужбина

Седой Василий
2. Дворянская кровь
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Чужбина

Королевская Академия Магии. Неестественный Отбор

Самсонова Наталья
Любовные романы:
любовно-фантастические романы
8.22
рейтинг книги
Королевская Академия Магии. Неестественный Отбор

Леди Малиновой пустоши

Шах Ольга
Любовные романы:
любовно-фантастические романы
6.20
рейтинг книги
Леди Малиновой пустоши

Жена на четверых

Кожина Ксения
Любовные романы:
любовно-фантастические романы
эро литература
5.60
рейтинг книги
Жена на четверых

Имя нам Легион. Том 3

Дорничев Дмитрий
3. Меж двух миров
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Имя нам Легион. Том 3

Её (мой) ребенок

Рам Янка
Любовные романы:
современные любовные романы
6.91
рейтинг книги
Её (мой) ребенок

Отмороженный 11.0

Гарцевич Евгений Александрович
11. Отмороженный
Фантастика:
боевая фантастика
рпг
попаданцы
фантастика: прочее
фэнтези
5.00
рейтинг книги
Отмороженный 11.0

Утопающий во лжи 3

Жуковский Лев
3. Утопающий во лжи
Фантастика:
фэнтези
рпг
5.00
рейтинг книги
Утопающий во лжи 3

Третий. Том 4

INDIGO
Вселенная EVE Online
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
5.00
рейтинг книги
Третий. Том 4

Небо для Беса

Рам Янка
3. Самбисты
Любовные романы:
современные любовные романы
5.25
рейтинг книги
Небо для Беса