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

ЖАНРЫ

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

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

Шрифт:

Контрольные вопросы

1. Как обратиться к первому и последнему элементам массива SomeArray[25]?

2. Как объявить многомерный массив?

3. Выполните инициализацию элементов многомерного массива, созданного при ответе на вопрос 2.

4. Сколько элементов содержит массив SomeArray[10][5][20]?

5. Каково максимальное число элементов, которые можно добавить в связанный список?

6. Можно ли в связанном списке использовать индексы?

7. Каким является последний символ в строке "Сергей — хороший парень"?

Упражнения

1. Объявите

двухмерный массив, который представляет поле для игры в крестики и нолики.

2. Запишите программный код, инициализирующий значением 0 все элементы созданного перед этим массива.

3. Объявите класс узла Node, поддерживающего целые числа.

4. Жучки: что неправильно в следующей программе?

unsigned short SomeArray[5][4];

for (int i = 0; i<4; i++)

for (int j = 0; j<5; ]++)

SomeArray[i][j] = i+j;

5. Жучки: что неправильно в следующей программе?

unsigned short SomeArray[5][4];

for (int i = 0; i<=5; i++)

for (int j = 0; j<=4; j++)

SomeArray[i][j] = 0;

День 13-й. Полиморфизм

На прошлом занятии вы узнали, как создавать виртуальные функции в производных классах. На этом занятии речь пойдет об основном составляющем ядре полиморфизма — возможности во время выполнения программы связывать специфические объекты производных классов с указателями базового класса. Сегодня вы узнаете:

• Что такое множественное наследование и как его использовать

• Что представляет собой виртуальное наследование

• Что такое абстрактные типы данных

• Что такое чистые виртуальные функции

Проблемы с одиночным наследованием

Давайте продолжим работу над программой о животных и предположим, что в ней теперь используется два класса, произведенных от какого-то общего класса. Один — Bird, посвященный птицам, а другой — Mammals, посвященный млекопитающим. Класс Bird содержит функцию-член Fly, задающую возможность полета. Класс Mammals разбит на ряд подклассов, включая класс лошадей — Horse. Класс содержит две функции- члена — Whinny и Gallop, объявляющих ржание и бег галопом соответственно.

Но внезапно у вас возникает желание создать новый весьма интересный мифический объект — крылатого Пегаса (Pegasus), который был бы чем-то вроде гибрида между Horse и Bird. Сразу предупредим, что, используя только одиночное наследование, вам сложно будет справиться с этой задачей.

Если объявить объект Pegasus как член класса Bird, то для него станут недоступными функции Whinny и Gallop. Если Pegasus объявить как объект класса Horse, то ему станет недоступной функция Fly.

Первое решение может состоять в том, чтобы скопировать метод Fly в класс Horse, после чего в этом классе создать объект Pegasus. При этом оба класса (Bird и Horse) будут содержать один и тот же метод Fly, и при изменении метода в одном классе нужно будет не забыть внести соответствующие изменения в другом классе. Хорошо, если таких классов будет только два. Если вам придется вносить изменения в программу через некоторое время после ее создания, будет сложно вспомнить, в каких еще классах представлен этот метод.

Когда вы захотите создать списки объектов классов Bird и Horse, перед вами

возникнет еще одна проблема. Хотелось бы, чтобы объект Pegasus был представлен в обоих списках, но в данном случае это невозможно.

Для решения возникшей проблемы можно использовать несколько подходов. Haпример, можно переименовать слишком "лошадиный" метод Gallop в более обтекаемый Move, после чего заместить этот метод в объекте Pegasus таким образом, чтобы он выполнял функцию метода Fly. В других объектах класса Horse метод Move будет выполняться так же, как раньше выполнялся метод Gallop. Для объекта Pegasus можно даже определить, что короткие дистанции он должен преодолевать методом Gallop, а длинные — методом Fly:

Pegasus::Move(long distance)

{

if (distance > veryFar)

fly(distance);

else

gallop(distance);

}

Но и этот подход имеет ряд ограничений, поскольку объект уже не сможет летать на короткие дистанции и бегать на длинные. Может быть, все же просто перенести метод Fly в класс Horse, как показано в листинге 13.1? Проблема состоит в том, что лошади, в большинстве своем, летать не умеют, поэтому во всех объектах этого класса, за исключением объекта Pegasus, данный метод не должен ничего выполнять.

Листинг 13.1. Умеют ли лошади летать...

1: // Листинг 13.1. Умеют ли лошади летать...

2: // Фильтрация метода Fly в классе Horse

3:

4: #include <iostream.h>

5:

6: class Horse

7: {

8: public:

9: void Gallop{ cout << "Galloping...\n"; }

10: virtual void Fly { cout << "Horses can't fly.\n"; }

11: private:

12: int itsAge;

13: };

14:

15: class Pegasus : public Horse

16: {

17: public:

18: virtual void Fly { cout << "I can fly! I can fly! I can fly!\n"; }

19: };

20:

21: const int NumberHorses = 5;

22: int main

23: {

24: Horse* Ranch[NumberHorses];

25: Horse* pHorse;

26: int choice,i;

27: for (i=0; i<NumberHorses; i++)

28: {

29: cout << "(1)Horse (2)Pegasus: ";

30: cin >> choice;

31: if (choice == 2)

32: pHorse = new Pegasus;

33: else

34: pHorse = new Horse;

35: Ranch[i] = pHorse;

36: }

37: cout << "\n";

38: for (i=0; i<NumberHorses; i++)

39: {

40: Ranch[i]->Fly;

41: delete Ranch[i];

42: }

43: return 0;

44: }

Результат:

(1)Horse (2)Pegasus; 1

(1)Horse (2)Pegasus: 2

(1)Horse (2)Pegasus: 1

(1)Horse (2)Pegasus: 2

(1)Horse (2)Pegasus: 1

Horses can't fly.

I can fly! I can fly! I can fly!

Horses can't fly.

I can fly! I can fly! I can fly!

Horses can't fly.

Анализ: Безусловно, эта программа будет работать ценой добавления в класс Horse редко используемого метода Fly. Это произошло в строке 10. Для объектов данного класса этот метод констатирует факт, что лошади летать не умеют. И только для объекта Pegasus метод замещается в строке 18 таким образом, что при вызове его объект заявляет, что умеет летать.

Поделиться с друзьями: