Освой самостоятельно С++ за 21 день.
Шрифт:
104: Mammal(age),
105: itsBreed(breed)
106: {
107: cout << "Dog(int, BREED) constructor...\n";
108: }
109:
110: Dog::~Dog
111: {
112: cout << "Dog destructor...\n";
113: }
114: int main
115: {
116: Dog fido;
117: Dog rover(5);
118: Dog buster(6,8);
119: Dog yorkie (3,GOLDEN);
120: Dog dobbie (4,20,DOBERMAN);
121: fido.Speak;
122: rover.WagTail;
123: cout << "Yorkie is " << yorkie.GetAge << " years old\n";
124: cout << "Dobbie weighs ";
125: cout << dobbie.GetWeight << " pounds\n";
126: return 0;
127: }
Примечание:Для
Результат:
1: Mammal constructor...
2: Dog constructor...
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. Этот конструктор принимает два параметра. Первое значение вновь инициализируется обращением к соответствующему конструктору базового класса, тогда как второе берется из переменной базового
Самостоятельно проанализируйте работу остальных конструкторов в программе, чтобы закрепить полученные знания. Обращайте внимание, какие переменные можно инициализировать одновременно с инициализацией конструктора, а в каких случаях инициализацию следует выполнять в теле конструктора.
Для удобства анализа работы программы строки вывода были пронумерованы. Первые две строки вывода соответствуют инициализации объекта 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 <iostream.h>
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"; }