Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Документ Microsoft Office Word (2).docx
Скачиваний:
44
Добавлен:
09.02.2015
Размер:
842.69 Кб
Скачать

Наследование

Для создания классов с добавленной функциональностью вводят наследование. Класс-наследник имеет поля и функции-члены базового класса, но не имеет права обращаться к собственным (private) полям и функциям базового класса. В этом и заключается разница между собственными и защищёнными членами.  Класс-наследник может добавлять свои поля и функции или переопределять функции базового класса.  По умолчанию, конструктор наследника без параметров вызывает конструктор базового класса, а затем конструкторы добавленных элементов. Деструктор работает в обратном порядке. Другие конструкторы приходится определять каждый раз заново. К счастью, это можно сделать вызовом конструктора базового класса.

class ArrayWithAdd : public Array {

ArrayWithAdd(int n) : Array(n) {}

ArrayWithAdd() : Array() {}

ArrayWithAdd(const Array& a) : Array(a) {}

void Add(const Array& a);

};

Наследник - это больше чем базовый класс, поэтому он может использоваться везде, где используется базовый класс, но не наоборот.  Наследование бывает публичным, защищённым и собственным. При публичном наследовании, публичные и защищённые члены базового класса сохраняют свой статус, а к собственным не могут обращаться даже функции-члены наследника. Защищённое наследование отличается тем, что при нём публичные члены базового класса являются защищёнными членами наследника. При собственном наследовании, ни к каким членам базового класса даже функции-члены наследника не имают права обращаться. Как правило, публичное наследование встречается значительно чаще других.  Класс может быть наследником нескольких классов. Это называется множественным наследованием. Такой класс обладает полями и функциями-членами всех его предков. Например, класс FlyingCat (ЛетающийКот) может быть наследником классов Cat (Кот) и FlyingAnimal (ЛетающееЖивотное)

class Cat {

...

void Purr();

...

};

class FlyingAnimal {

...

void Fly();

...

};

class FlyingCat : public Cat, public FlyingAnimal {

...

PurrAndFly() {Purr(); Fly();}

...

};

Полиморфизм

Полиморфизмом в программировании называется переопределение наследником функций-членов базового класса, например

class Figure {

...

void Draw() const;

...

};

class Square : public Figure {

...

void Draw() const;

...

};

class Circle : public Figure {

...

void Draw() const;

...

};

В этом примере, какая из функций будет вызвана - Circle::Draw(), Square::Draw() или Figure::Draw(), определяется во время компиляции. К примеру, если написать

Figure* x = new Circle(0,0,5);

x->Draw();

то будет вызвана Figure::Draw(), поскольку x - объект класса Figure. Такой полиморфизм называется статическим.  Но в C++ есть и динамический полиморфизм, когда вызываемая функция определяется во время выполнения. Для этого функции-члены должны быть виртуальными.

class Figure {

...

virtual void Draw() const;

...

};

class Square : public Figure {

...

virtual void Draw() const;

...

};

class Circle : public Figure {

...

virtual void Draw() const;

...

};

Figure* figures[10];

figures[0] = new Square(1, 2, 10);

figures[1] = new Circle(3, 5, 8);

...

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

figures[i]->Draw();

В этом случае для каждого элемента будет вызвана Square::Draw() или Circle::Draw() в зависимости от вида фигуры.  Чисто виртуальной функцией называется функция-член, которая не определена в базовом классе, а только в наследниках:

class Figure {

...

virtual void Draw() const = 0;

);

Вот это = 0 и значит, что функция чисто виртуальная.  Абстрактным классом называется такой, у которого есть хотя бы одна чисто виртуальная функция-член. Объекты таких классов создавать запрещено. Абстрактные классы используются как интерфейсы.

Друзья

Функции-друзья — это функции, не являющиеся функциями-членами и тем не менее имеющие доступ к защищённым и собственным полям и функциям-членам класса. Они должны быть описаны в теле класса как friend. Например:

class Matrix {

...

friend Matrix Multiply(Matrix m1, Matrix m2);

...

};

Matrix Multiply(Matrix m1, Matrix m2) {

...

}

Здесь функция Multiply может обращаться к любым полям и функциям-членам класса Matrix.  Существуют также классы-друзья. Если класс A - друг класса B, то все его функции-члены могут обращаться к любым полям и функциям членам класса B. Например:

class Matrix {

...

friend class Vector;

...

};

Однако в С++ не действует правило «друг моего друга — мой друг».