Джесс Либерти - Освой самостоятельно С++ за 21 день.
- Название:Освой самостоятельно С++ за 21 день.
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Джесс Либерти - Освой самостоятельно С++ за 21 день. краткое содержание
В книге широко представлены возможности новейшей версии программного продукта Microsoft Visual C++. Подробно описаны средства и подходы программирования современных профессиональных приложений. Материалы книги дополнены многочисленными демонстрационными программами, в процессе разработки которых максимально используются возможности программных инструментов Microsoft Visual Studio. Особое внимание уделено новинкам версии 6.0 и новейшим технологиям объектно-ориентированного программирования, включая использование библиотеки MFC и шаблонов классов, а также создание связанных списков. Отдельное занятие посвящено вопросам объектно-ориентированного анализа и проектирования приложений. Подробно рассмотрены все средства и подходы конструирования собственных пользовательских классов.
Книга рассчитана на широкий круг читателей, интересующихся современными проблемами программирования.
Освой самостоятельно С++ за 21 день. - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
96: cout << " " << Edie.GetLastName().GetString();
97: cout << ".\nAddress: ";
98: cout << Edie.GetAddress().GetString();
99: cout << ".\nSalary: " ;
100: cout << Edie.GetSalary();
101: cout << endl;
102:
103: }
104:
105: void rPrintFunc (const Employee& Edie)
106: {
107: cout << "Name: ";
108: cout << Edie.GetFirstName().GetString();
109: cout << " " << Edie.GetLastName().GetString();
110: cout << "\nAddress: ";
111: cout << Edie.GetAddress().GetString();
112: cout << "\nSalary: " ;
113: cout << Edie.GetSalary();
114: cout << endl;
115: }
Результат:
String(char*) constructor
String(char*) constructor
String(char*) constructor
String(char*) constructor
String destructor
String(char*) constructor
Constructor count: 5
Name: Edythe Levine
Address: 1461 Shore Parkway
Salary: 20000
Constructor count; 5
String(String&) constructor
String(String&) constructor
String(String&) constructor
Name: Edythe Levine
Address: 1461 Shore Parkway
Salary: 20000
String destructor
String destructor
String destructor
Constructor count: 8
String destructor
String destructor
String destructor
String destructor
Анализ:Как видно по данным, выводимым программой, в процессе создания одного объекта Employee создается пять объектов класса String. Когда объект Employee передается в функцию rPrintFunc() как ссылка, дополнительные объекты Employee не создаются. Соответственно не создаются и дополнительные объекты String. (Все они, кстати, также автоматически передаются как ссылки.)
Когда объект Employee передается в функцию PrintFunc() как значение, создается копия объекта Employee вместе с тремя объектами класса String (для этого используется конструктор-копировщик).
Различные пути передачи функциональности классу
В некоторых случаях одному классу необходимо передать некоторые свойства другого. Предположим, например, что вам необходимо создать класс каталога деталей PartsCatalog. На основе класса PartsCatalog предполагается создать коллекцию объектов, представляющую различные запчасти с уникальными номерами. В базе данных на основе класса PartsCatalog запрещается дублирование объектов, а для доступа к объекту необходимо указать его идентификационный номер.
Ранее, в обзоре за вторую неделю, уже был объявлен и детально проанализирован класс PartsList. Чтобы не начинать работу с нуля, можно взять этот класс за основу при объявлении класса PartsCatalog. Для этого можно вложить класс PartsList в класс PartsCatalog, чтобы затем делегировать классу PartsCatalog ответственность за поддержание связанного списка в класс PartsList.
Существует альтернативный путь. Можно произвести класс PartsCatalog от класса PartsList, таким образом унаследовав все свойства последнего. Помните однако, что открытое наследование (со спецификатором public) предполагает логическую принадлежность производного класса более общему базовому классу. Действительно ли в нашем случае класс PartsCatalog является частным проявлением класса PartList? Чтобы разобраться в этом, попробуйте ответить на ряд вопросов.
1. Содержит ли базовый класс PartsList методы, не применимые в классе PartsCatalog? Если да, то, вероятно, от открытого наследования лучше отказаться.
2. Будет ли один объект класса PartsCatalog соответствовать одному объекту класса PartsList? Если для создания объекта требуется не менее двух объектов PartsList, то, безусловно, необходимо применять вложение.
3. Обеспечит ли наследование от базового класса преимущества в работе благодаря использованию виртуальных функций или методов доступа к защищенным членам базового класса? В случае положительного ответа имеет смысл воспользоваться открытым или закрытым наследованием.
Ответив на приведенные выше вопросы, вы должны принять решение, использовать ли вам в программе открытое наследование, закрытое наследование (см. далее в этом занятии) или вложение. Познакомимся с некоторыми терминами, которые потребуются нам при дальнейшем обсуждении этой темы.
• Вложение — объект, относящийся к другому классу, используется в текущий класс.
• Делегирование — передача ответственности за выполнение специальных функций вложенному классу.
• Выполнение средствами класса — реализация специальных функций в классе за счет другого класса без использования открытого наследования.
Делегирование
Почему же класс PartsCatalog нельзя произвести от PartsList? Дело в том, что класс PartsCatalog должен обладать совершенно иными свойствами и ero невозможно представить как частную реализацию класса PartsList. Посмотрите, класс PartsList — это коллекция объектов, упорядоченная по возрастанию номеров, элементы которой могут повторяться. Класс PartsCatalog представляет неупорядоченную коллекцию уникальных объектов.
Конечно, при желании можно произвести класс PartsList от класса PartsList со спецификатором public, после чего соответствующим образом заместить функцию Insert() и оператор индексирования ([]). Однако такие действия крайне нелогичны и противоречат самой сути наследования. Вместо этого следует создать новый класс PartsCatalog, в котором нет оператора индексирования, не разрешается дублирование записей и перегружается operator+ для суммирования наборов записей. Функцию управления связанным списком оставим классу PartsList.
Попробуем сначала решить эту задачу путем вложения одного класса в другой с делегированием ответственности от класса классу, как показано в листинге 15.5.
Листинг 15.5. Делегирование ответственности классу PartsList, включенному в класс PartsCatalog
1: #include
2:
3: // **************** Класс Part ************
4:
5: // Абстрактный базовый класс всех деталей
6: class Part
7: {
8: public:
9: Part():itsPartNumber(1) { }
10: Part(int PartNumber):
11: itsPartNumber(PartNumber){ }
12: virtual ~Part(){ }
13: int GetPartNumber() const
14: { return itsPartNumber; }
15: virtual void Display() const =0;
16: private:
17: int itsPartNumber;
18: };
19:
20: // выполнение чистой виртуальной функции в
21: // стандартном виде для всех производных классов
22: void Part::Display() const
23: {
24: cout << "\nPart Number: " << itsPartNumber << endl;
25: }
26:
27: // ************ Автомобильные детали **********
28:
29: class CarPart : public Part
30: {
31: public:
32: CarPart():itsModelYear(94){ }
33: CarPart(int year, int partNumber);
34: virtual void Display() const
35: {
36: Part::Display();
37: cout << "Model Year: ";
38: cout << itsModelYear << endl;
39: }
40: private:
41: int itsModelYear;
42: };
43:
44: CarPart::CarPart(int year, int partNumber):
45: itsModelYear(year),
46: Part(partNumber)
47: { }
48:
49:
50: // ************* Авиационные детали ************
51:
52: class AirPlanePart : public Part
53: {
54: public:
55: AirPlanePart():itsEngineNumber(1){ }
56: AirPlanePart
57: (int EngineNumber, int PartNumber)
58: virtual void Dlsplay() const
59: {
60: Part::Display();
61: cout << " Engine No.: ";
62: cout << itsEngineNumber << endl;
63: }
64: private:
65: int itsEngineNumber;
66: };
67:
68: AirPlanePart::AirPlanePart
69: (int EngineNumber, int PartNumber):
70: itsEngineNumber(EngineNumber),
71: Part(PartNumber)
72: { }
73:
74: // *************** Узлы списка деталей **********
75: class PartNode
76: {
77: public:
78: PartNode (Part*);
79: ~PartNode();
80: void SetNext(PartNode * node)
81: { itsNext = node; }
82: PartNode * GetNext() const;
83: Part * GetPart() const;
84: private:
85: Part *itsPart;
86: PartNode * itsNext;
87: };
88: // Выполнение PartNode...
89:
90: PartNode::PartNode(Part* pPart):
Читать дальшеИнтервал:
Закладка: