Джесс Либерти - Освой самостоятельно С++ за 21 день.
- Название:Освой самостоятельно С++ за 21 день.
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Джесс Либерти - Освой самостоятельно С++ за 21 день. краткое содержание
В книге широко представлены возможности новейшей версии программного продукта Microsoft Visual C++. Подробно описаны средства и подходы программирования современных профессиональных приложений. Материалы книги дополнены многочисленными демонстрационными программами, в процессе разработки которых максимально используются возможности программных инструментов Microsoft Visual Studio. Особое внимание уделено новинкам версии 6.0 и новейшим технологиям объектно-ориентированного программирования, включая использование библиотеки MFC и шаблонов классов, а также создание связанных списков. Отдельное занятие посвящено вопросам объектно-ориентированного анализа и проектирования приложений. Подробно рассмотрены все средства и подходы конструирования собственных пользовательских классов.
Книга рассчитана на широкий круг читателей, интересующихся современными проблемами программирования.
Освой самостоятельно С++ за 21 день. - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
3: Mammal(int) constructor...
4: Dog(int) constructor...
5: Mammal(int) constructor...
6: Dog(int, int) constructor...
7: Mammal(int) constructor...
8: Dog(int, BREED) constructor....
9: Mammal(int) constructor...
10: Dog(int, int, BREED) constructor...
11: Mammal sound!
12: Tail wagging...
13: Yorkie is 3 years old.
14: Dobbie weighs 20 pounds.
15: Dog destructor..,
16: Mammal destructor...
17: Dog destructor...
18: Mammal destructor...
19: Dog destructor...
20: Mammal destructor...
21: Dog destructor...
22: Mammal destructor...
23: Dog destructor, . .
24: Mammal destructor...
Анализ:В листинге 11.4 конструктор класса Mammal перегружен в строке 11 таким образом, чтобы принимать целочисленные значения возраста животного. В строках 61—66 происходит инициализация переменной itsAge значением 5, переданным в параметре конструктора.
В классе Dog в строках 35—39 создается пять перегруженных конструкторов. Первый — это конструктор, заданный по умолчанию. Второй принимает возраст и использует для этого тот же параметр, что и конструктор класса Mammal. Третий принимает возраст и вес, четвертый — возраст и породу, а пятый — возраст, вес и породу.
Обратите внимание, что в строке 74 конструктор по умолчанию класса Dog вызывает конструктор по умолчанию класса Mammal. Хотя в этом нет необходимости, но данная запись лишний раз документирует намерение вызвать именно базовый конструктор, не содержащий параметров. Базовый конструктор будет вызван в любом случае, но в данной строке это было сделано явно.
В строках 80—85 выполняется конструктор класса Dog, который принимает одно целочисленное значение. Во время инициализации (строки 81 и 82) возраст принимается из базового класса в виде параметра, после чего присваивается значение породы.
Другой конструктор класса Dog выполняется в строках 87—93. Этот конструктор принимает два параметра. Первое значение вновь инициализируется обращением к соответствующему конструктору базового класса, тогда как второе берется из переменной базового класса itsWeight самим конструктором класса Dog. Обратите внимание, что присвоение значения переменной базового класса не может осуществляться на стадии инициализации конструктора произведенного класса. Поскольку в классе Mammal нет конструктора, присваивающего значение этой переменной, то присвоение значения должно выполняться в теле конструктора класса Dog.
Самостоятельно проанализируйте работу остальных конструкторов в программе, чтобы закрепить полученные знания. Обращайте внимание, какие переменные можно инициализировать одновременно с инициализацией конструктора, а в каких случаях инициализацию следует выполнять в теле конструктора.
Для удобства анализа работы программы строки вывода были пронумерованы. Первые две строки вывода соответствуют инициализации объекта Fido с помощью конструкторов, заданных по умолчанию.
Строки 3 и 4 соответствуют созданию объекта rover, а строки 5 и 6 — объекта buster. Обратите внимание, что в последнем случае из конструктора класса Dog с двумя целочисленными параметрами происходит вызов конструктора класса Mammal, содержащего один целочисленный параметр.
После создания всех объектов программа использует их и наконец выходит за область видимости этих объектов. Удаление каждого объекта сопровождается обращением к деструктору класса Dog, после чего следует обращение к деструктору класса Mammal.
Замещение функций
Объект класса Dog имеет доступ ко всем функциям-членам класса Mammal, а также к любой функции-члену, чье объявление добавлено в класс Dog, например к функции WagTaill(). Но кроме этого, базовые функции могут быть замещены в производном классе. Под замещением базовой функции понимают изменение ее выполнения в производном классе для объектов, созданных в этом классе.
Если в производном классе создается функция с таким же возвратом и сигнатурой как и в базовом классе, но выполняемая особым образом, то имеет место замещение метода.
В случае замещения функций должно сохраняться соответствие между типом возврата и сигнатурой функций в базовом классе. Под сигнатурой понимают установки, заданные в прототипе функции, включая ее имя, список параметров и, в случае использования, ключевое слово const.
В листинге 11.5 показано замещение в классе Dog функции Speak(), объявленной в классе Mammal. Для экономии места знакомые по предыдущим листингам объявления методов доступа в этом примере были опущены.
Листинг 11.5. Замещение метода базового класса в производном классе
1: //Листинг 11.5. Замещение метода базового класса в производном классе
2:
3: #include
4: enum BREED { GOLDEN, CAIRN, DANDIE, SHETLAND, DOBERMAN, LAB };
5:
6: class Mammal
7: {
8: public:
9: // Конструкторы
10: Mammal() { cout << "Mammal constructor...\n"; }
11: ~Mammal() { cout << "Mammal destructor...\n"; }
12:
13: //Другие методы
14: void Speak()const { cout << "Mammal sound!\n"; }
15: void Sleep()const { cout << "shhh. I'm sleeping.\n"; }
16:
17:
18: protected:
19: int itsAge;
20: int itsWeight;
21: };
22:
23: class Dog : public Mammal
24: {
25: public:
26:
27: // Конструкторы
28: Dog(){ cout << "Dog constructor...\n"; }
29: ~Dog(){ cout << "Dog destructor...\n"; }
30:
31: // Другие методы
32: void WagTail() const { cout << "Tail wagging...\n"; }
33: void BegForFood() const { cout << "Begging for food...\n"; }
34: void Speak() const { cout << "Woof!\n"; }
35:
36: private:
37: BREED itsBreed;
38: };
39:
40: int main()
41: {
42: Mammal bigAnimal;
43: Dog fido;
44: bigAnimal.Speak();
45: fido.Speak();
46: return 0;
47: }
Результат:
Mammal constructor...
Mammal constructor...
Dog constructor...
Mammal sound!
Woof!
Dog destructor...
Mammal destructor...
Mammal destructor...
Анализ:В строке 34 в классе Dog происходит замещение метода базового класса
Speak(), в результате чего в случае вызова этой функции объектом класса Dog на экран выводится Woof!. В строке 42 создается объект bigAnimal класса Mammal, в результате чего вызывается конструктор класса Mammal и на экране появляется первая строка. В строке 43 создается объект Fido класса Dog, что сопровождается последовательным вызовом сначала конструктора класса Mammal, а затем конструктора класса Dog. Соответственно на экран выводится еще две строки.
В строке 44 объект класса Mammal вызывает метод Speak(), а в строке 45 уже объект класса Dog обращается к этому методу. На экран при этом выводится разная информация, так как метод Speak() в классе Dog замещен. Наконец выполнение программы выходит за область видимости объектов и для их удаления вызываются соответствующие пары деструкторов.
Перегрузка или замещение
Эти схожиеподходы приводят почти к одинаковым результатам. При перегрузке метода создается несколько вариантов этогометода с одним и тем же именем, но с разными сигнатурами. При замещении в производном классе используется метод с тем же именем и сигнатурой, что и в базовом классе, но с изменениями в теле функции.
Сокрытие метода базового класса
В предыдущем примере при обращении к методу Speak() из объекта класса Dog программа выполнялась не так, как было указано при объявлении метода Speak() в базовом классе. Казалось бы, это то, что нам нужно. Если в классе Mammal есть некоторый метод Move(), который замещается в классе Dog, то можно сказать, что метод Move() класса Dog скрывает метод с тем же именем в базовом классе. Однако в некоторых случаях результат может оказаться неожиданным.
Читать дальшеИнтервал:
Закладка: