Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
04-09-2015_19-17-13 / Конспект лекций.doc
Скачиваний:
98
Добавлен:
01.03.2016
Размер:
1.31 Mб
Скачать

13.2 Абстрактные классы

Абстрактным называется класс, в котором есть хотя бы одна чистая (пустая) виртуальная функция.

Чистой виртуальной называется компонентная функция, которая имеет следующее определение:

virtual тип имя_функции(список_формальных_параметров) = 0;

Чистая виртуальная функция ничего не делает и недоступна для вызовов. Ее назначение – служить основой для подменяющих ее функций в производных классах. Абстрактный класс может использоваться только в качестве базового для производных классов.

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

Пример

class Base{

public:

Base(); // конструктор по умолчанию

Base(const Base&); // конструктор копирования

virtual ~Base(); // виртуальный деструктор

virtual void Show()=0; // чистая виртуальная функция

// другие чистые виртуальные функции

protected:

// защищенные члены класса

private:

// часто остается пустым, иначе будет мешать будущим разработкам

};

class Derived: virtual public Base{

public:

Derived(); // конструктор по умолчанию

Derived(const Derived&); // конструктор копирования

Derived(параметры); // конструктор с параметрами

virtual ~Derived(); // виртуальный деструктор

void Show(); // переопределенная виртуальная функция

// другие переопределенные виртуальные функции

Derived& operator=(const Derived&); // перегруженная операция присваивания

// ее смысл будет понятен после прочтения главы 3

// другие перегруженные операции

protected:

// используется вместо private, если ожидается наследование

private:

// используется для деталей реализации

};

По сравнению с обычными классами абстрактные классы пользуются “ограниченными правам”. А именно:

  • невозможно создать объект абстрактного класса;

  • абстрактный класс нельзя употреблять для задания типа параметра функции или типа возвращаемого функцией значения;

  • абстрактный класс нельзя использовать при явном приведении типов; в то же время можно определить указатели и ссылки на абстрактный класс.

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

Пример

Сформируем односвязный список, содержащий объекты разных классов, производных от одного абстрактного класса.

#include<iostream.h>

#include<string.h>

// Абстрактный класс

class Person

{

public:

Person()

{strcpy(name,"NONAME"); age=0; next=0;};

Person(char*NAME,int AGE)

{ strcpy(name,NAME); age=AGE; next=0;}

virtual~Person(){};

virtual void Show()=0;

virtual void Input()=0;

friend class List; //для того, чтобы в классе List было доступно поле next

protected:

char name[20]; //имя

int age; //возраст

Person* next; //указатель на следующий объект в списке

};

//Производный класс- СТУДЕНТ

class Student:public Person{

public:

Student()

{grade=0;}

Student(char* NAME,int AGE,float GRADE):Person(NAME,AGE)

{grade=GRADE; }

void Show(){cout<<"name="<<name<<" age="<<age<<"grade="<<grade<<endl;}

void Input()

{cout<<"name=";cin>>name;

cout<<"age=";cin>>age;

cout<<"grade=";cin>>grade;}

protected:

float grade;//рейтинг

};

//Производный класс- Преподаватель

class Teacher:public Person{

public:

Teacher()

{work=0;}

Teacher(char* NAME,int AGE,int WORK):Person(NAME,AGE)

{ work=WORK;}

void Show(){cout<<"name="<<name<<" age="<<age<<" work="<<work<<endl;}

void Input()

{

cout<<"name=";cin>>name;

cout<<"age=";cin>>age;

cout<<"work=";cin>>work;}

protected:

int work;//стаж

};

//Класс СПИСОК

class List

{

private:

Person* begin;

public:

List(){begin=0;}

~List();

void Insert(Person*);

void Show();

};

List::~List()

{ Person*r;

while(begin!=0){ r=begin; begin=begin->next; delete r;}

}

void List::Insert(Person*p){

Person *r;

r=begin; begin=p; p->next=r;}

void List::Show()

{Person *r;

r=begin;

while(r!=0)

{r->Show(); r=r->next;}

}

void main()

{

List list;

Student* ps;

Teacher* pt;

ps=new Student("Иванов",21,50.5);

list.Insert(ps);

pt=new Teacher("Котов",34,10);

list.Insert(pt);

ps=new Student;

ps->Input();

list.Insert(ps);

pt=new Teacher;

pt->Input();

list.Insert(pt);

list.Show();

}

Соседние файлы в папке 04-09-2015_19-17-13