Джесс Либерти - Освой самостоятельно С++ за 21 день.

Скачивание начинается... Если скачивание не началось автоматически, пожалуйста нажмите на эту ссылку.
Жалоба
Напишите нам, и мы в срочном порядке примем меры.
Описание книги "Освой самостоятельно С++ за 21 день."
Описание и краткое содержание "Освой самостоятельно С++ за 21 день." читать бесплатно онлайн.
В книге широко представлены возможности новейшей версии программного продукта Microsoft Visual C++. Подробно описаны средства и подходы программирования современных профессиональных приложений. Материалы книги дополнены многочисленными демонстрационными программами, в процессе разработки которых максимально используются возможности программных инструментов Microsoft Visual Studio. Особое внимание уделено новинкам версии 6.0 и новейшим технологиям объектно-ориентированного программирования, включая использование библиотеки MFC и шаблонов классов, а также создание связанных списков. Отдельное занятие посвящено вопросам объектно-ориентированного анализа и проектирования приложений. Подробно рассмотрены все средства и подходы конструирования собственных пользовательских классов.
Книга рассчитана на широкий круг читателей, интересующихся современными проблемами программирования.
Нельзя брать там, находясь здесь
Если для объекта класса Dog объявлен метод WagTail(), который не принадлежит классу Mammal, то невозможно получить доступ к этому методу, используя указатель класса Mammal (если только этот указатель не будет явно преобразован в указатель класса Dog). Поскольку функция WagTail() не является виртуальной и не принадлежит классу Mammal, то доступ к ней можно получить только из объекта класса Dog или с помощью указателя этого класса.
Поскольку любые преобразования чреваты ошибками, создатели C++ допустили только явные преобразования типов. Всегда можно преобразовать любой указатель класса Mammal в указатель класса Dog, но есть более надежный и безопасный способ вызова метода WagTail(). Чтобы разобраться в тонкостях упомянутого метода, необходимо освоить множественное наследование, о котором речь пойдет на следующем занятии, или научиться работе с шаблонами, что будет темой занятия 20.
Дробление объекта
Следует обратить внимание, что вся магия виртуальных функций проявляется только при обращении к ним с помощью указателей и ссылок. Если передать объект как значение, то виртуальную функцию вызвать не удастся. Эта проблема показана в листинге 11.10.
Листинг 11.10. Дробление объекта при передаче его как значения
1: //Листинг 11.10. Дробление объекта при передачи его как значения
2:
3: #include <iostream.h>
4:
5: class Mammal
6: {
7: public:
8: Mammal():itsAge(1) { }
9: virtual ~Mammal() { }
10: virtual void Speak() const { cout << "Mammal speak!\n"; }
11: protected:
12: int itsAge;
13: };
14:
15: class Dog : public Mammal
16: {
17: public:
18: void Speak()const { cout << "Woof!\n"; }
19: };
20:
21: class Cat : public Mammal
22: {
23: public:
24: void Speak()const { cout << "Meow!\ri"; >
25: };
26:
27: void ValueFunction (Mammal);
28: void PtrFunction (Mammal*);
29: void RefFunction (Mammal&);
30: int main()
31: {
32: Mammal* ptr=0;
33: int choice;
34: while (1)
35: {
36: bool fQuit = false;
37: cout << "(1)dog (2)cat (0)Quit: ";
38: cin >> choice;
39: switch (choice)
40: {
41: case 0: fQuit = true;
42: break;
43: case 1: ptr = new Dog;
44: break;
45: case 2: ptr = new Cat;
46: break;
47: default: ptr = new Mammal;
48: break;
49: }
50: if (fQuit)
51: break;
52: PtrFunction(ptr);
53: RefFunction(*ptr);
54: ValueFunction(*ptr);
55: }
56: return 0;
57: }
58:
59: void ValueFunction (Mammal MammalValue)
60: {
61: MammalValue.Speak();
62: }
63:
64: void PtrFunction (Mammal * pMammal)
65: {
66: pMammal->Speak();
67: }
68:
69: void RefFunction (Mammal & rMammal)
70: {
71: rMammal.Speak();
72: }
Результат:
(1)dog (2)cat (0)Quit: 1
Woof
Woof
Mammal Speak!
(1)dog (2)cat (0)Quit: 2
Meow!
Meow!
Mammal Speak!
(1)dog (2)cat (0)Quit: 0
Анализ: В строках 5—25 определяются классы Mammal, Dog и Cat. Затем объявляются три функции — PtrFunction(), RefFunction() и ValueFunction(). Они принимают соответственно указатель класса Mammal, ссылку класса Mammal и объект класса Mammal. После чего выполняют одну и ту же операцию — вызывают метод Speak().
Пользователю предлагается выбрать объект класса Dog или класса Cat, после чего в строках 43—46 создается указатель соответствующего типа.
Судя по информации, выведенной программой на экран, пользователь первый раз выбрал объект класса Dog, который был создан в свободной области памяти 43-й строкой программы. Затем объект класса Dog передается в три функции с помощью указателя, с помощью ссылки и как значение.
В том случае, когда в функцию передавался адрес объекта с помощью указателя или ссылки, успешно выполнялась функция-член Dog->Speak(). На экране компьютера дважды появилось сообщение, соответствующее выбранному пользователем объекту.
Разыменованный указатель передает объект как значение. В этом случае функция распознает принадлежность переданного объекта классу Mammal, компилятор разбивает объект класса Dog пополам и использует только ту часть, которая была создана конструктором класса Mammal. В таком случае вызывается версия метода Speak(), которая была объявлена для класса Mammal, что и отобразилось в информации, выведенной программой на экран.
Те же действия и с тем же результатом были выполнены затем и для объекта класса Cat.
Виртуальные деструкторы
В том случае, когда ожидается указатель на объект базового класса, вполне допустима и часто используется на практике передача указателя на объект производного класса. Что произойдет при удалении указателя, ссылающегося на объект производного класса? Если деструктор будет объявлен как виртуальный, то все пройдет отлично — будет вызван деструктор соответствующего производного класса. Затем деструктор производного класса автоматически вызовет деструктор базового класса, и указанный объект будет удален целиком.
Отсюда следует правило: если в классе объявлены виртуальные функции, то и деструктор должен быть виртуальным.
Виртуальный конструктор-копировщик
Конструкторы не могут быть виртуальными, из чего можно сделать вывод, что не может быть также виртуального конструктора-копировщика. Но иногда требуется, чтобы программа могла передать указатель на объект базового класса и правильно скопировать его в объект производного класса. Чтобы добиться этого, необходимо в базовом классе создать виртуальный метод Clone(). Метод Clone() должен создавать и возвращать копию объекта текущего класса.
Поскольку в производных классах метод Clone() замещается, при вызове его создаются копии объектов, соответствующие выбранному классу. Программа, использующая этот метод, показана в листинге 11.11.
Листинг 11.11. Виртуальный конструктор-копировщик
1: //Листинг 11.11. Виртуальный конструктор-копировщик
2:
3: #include <iostream.h>
4:
5: class Mammal
6: {
7: public:
8: Mammal():itsAge(1) { cout << "Mammal constructor...\n"; }
9: virtual ^Mammal() { cout << "Mammal destructor...\n"; }
10: Mammal (const Mammal & rhs);
11: virtual void Speak() const { cout << "Mammal speak!\n"; }
12: virtual Mammal* Clone() { return new Mammal(*this); }
13: int GetAge()const { return itsAge; }
14: protected:
15: int itsAge;
16: };
17:
18: Mammal::Mammal (const Mammal & rhs):itsAge(rhs.GetAge())
19: {
20: cout << "Mammal Copy Constructor...\n";
21: }
22:
23: class Dog : public Mammal
24: {
25: public:
26: Dog() { cout << "Dog constructor...\n"; }
27: virtual ~Dog() { cout << "Dog destructor...\n"; }
28: Dog (const Dog & rhs);
29: void Speak()const { cout << "Woof!\n"; }
30: virtual Mammal* Clone() { return new Dog(*this); }
31: };
32:
33: Dog::Dog(const Dog & rhs):
34: Mammal(rhs)
35: {
36: cout << "Dog copy constructor...\n";
37: }
38:
39: class Cat : public Mammal
40: {
41: public:
42: Cat() { cout << "Cat constructor,,,\n"; }
43: ~Cat() { cout << "Cat destructor...\n"; }
44: Cat (const Cat &);
45: void Speak()const { cout << "Meow!\n"; }
46: virtual Mammal* Clone() { return new Cat(*this); }
47: };
48:
49: Cat::Cat(const Cat & rhs):
50: Mammal(rhs)
51: {
52: cout << "Cat copy constructor..,\n";
53: }
54:
55: enum ANIMALS { MAMMAL, D0G, CAT };
56: const int NumAnimalTypes = 3;
57: int main()
58: {
59: Mammal *theArray[NumAnimalTypes];
60: Mammal* ptr;
61: int choice, i;
62: for ( i = 0; i<NumAnimalTypes; i++)
63: {
64: cout << "(1)dog (2)cat (3)Mammal: ";
65: cin >> choice;
66: switch (choice)
67: {
68: case DOG: ptr = new Dog;
69: break;
70: case CAT: ptr = new Cat;
71: break;
72: default: ptr = new Mammal;
73: break;
74: }
75: theArray[i] = ptr;
76: }
77: Mammal *OtherArray[NumAnimalTypes];
78: for (i=0;i<NumAnimalTypes;i++)
79: {
80: theArray[i]->Speak();
81: OtherArray[i] = theArray[i]->Clone();
82: }
83: for (i=0;i<NumAnimalTypes;i++)
84: OtherArray[i]->Speak();
85: return 0;
86: }
Результат:
1: (1)dog (2)cat (3)Mammal: 1
2: Mammal constructor...
3: Dog constructor...
4: (1)dog (2)cat (3)Mammal: 2
5: Mammal constructor...
6: Cat constructor...
7: (1)dog (2)cat (3)Mammal: 3
8: Mammal constructor...
9: Woof!
10: Mammal Copy Constructor...
11: Dog copy constructor...
12: Meow!
13: Mammal Copy Constructor...
14: Cat copy constructor...
15: Mammal speak!
16: Mammal Copy Constructor...
17: Woof!
18: Meow!
19: Mammal speak!
Анализ: Листинг 11.11 похож на два предыдущих листинга, однако в данной программе в классе Mammal добавлен один новый виртуальный метод — Clone(). Этот метод возвращает указатель на новый объект класса Mammal, используя конструктор-копировщик, параметр которого представлен указателем <<this.
Подписывайтесь на наши страницы в социальных сетях.
Будьте в курсе последних книжных новинок, комментируйте, обсуждайте. Мы ждём Вас!
Похожие книги на "Освой самостоятельно С++ за 21 день."
Книги похожие на "Освой самостоятельно С++ за 21 день." читать онлайн или скачать бесплатно полные версии.
Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.
Отзывы о "Джесс Либерти - Освой самостоятельно С++ за 21 день."
Отзывы читателей о книге "Освой самостоятельно С++ за 21 день.", комментарии и мнения людей о произведении.