Студопедия
Случайная страница | ТОМ-1 | ТОМ-2 | ТОМ-3
АрхитектураБиологияГеографияДругоеИностранные языки
ИнформатикаИсторияКультураЛитератураМатематика
МедицинаМеханикаОбразованиеОхрана трудаПедагогика
ПолитикаПравоПрограммированиеПсихологияРелигия
СоциологияСпортСтроительствоФизикаФилософия
ФинансыХимияЭкологияЭкономикаЭлектроника

Абстрактные базовые классы и чисто виртуальные функции

Наследование классов | Применение наследования | Использование объектов производного класса в качестве объектов базового класса | Dynamic_cast <тип *> (выражение). | Информация о типе во время выполнения (RTTI) (лучше почитать после обсуждения виртуальных функций). | Конструкторы, деструктор и перегрузка опрации присваивания в производном классе. | Виртуальные функции |


Читайте также:
  1. Apple намерена стать экологически чистой компанией
  2. III. B. Функции слова ONE
  3. Other Functions of Money. Другие функции денег
  4. V) Массивы и функции
  5. VIII–IX классы
  6. Абстрактные базовые классы и чисто виртуальные функции.

Класс можно представлять себе как носитель абстрактной концепции: коллекции различного вида объектов или общего интерфейса коллекции различного вида объектов. Никакого объекта на основе только той информации, которая содержится в таком классе, сконструировать нельзя. Это – абстрактный класс. Абстрактный класс может использоваться только как базовый класс. В классы, производные от абстрактного класса, добавляется уже больше информации, поля и/или функции-члены. Класс, порожденный из абстрактного базового класса, может еще продолжать оставаться абстрактным классом. В такой класс может быть добавлена дополнительная информация, пока не появится возможность создавать объекты.

 

Так как никакого объекта абстрактного класса создать нельзя, то конструктор класса, если таковой вообще имеется, не может быть вызван “в одиночку”. Конструктор абстрактного класса может быть использован только в списке инициализации в конструкторе его производного класса. Абстрактный класс не обязан иметь деструктора. Однако, если деструктор имеется, то он должен быть виртуальным.

 

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

 

Для того, чтобы указать (пометить), что класс является абстрактным, нужно объявить хотя бы одну функцию-член как чисто виртуальную функцию. Используется такой синтаксис:

 

virtual typeT function_name(parameter_list) = 0;

 

где typeT – тип возвращаемого значения (он может быть, например, void).

 

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

 

Пример 15-2. Абстрактные классы и чисто виртуальные функции

 

#include <iostream.h>

#include <math.h>

 

class Point

{

double x;

double y;

public:

Point(double i, double j): x(i), y(j) { }

void print() const

{ cout << "(" << x << ", " << y << ")"; }

};

 

class Figure

{

Point center;

public:

Figure (double i = 0, double j = 0): center(i, j) { }

Point& location() {return center;} // возвращает lvalue

void move(Point p) {center = p; draw();}

virtual void draw() = 0; // рисует фигуру

virtual void rotate(double) = 0; // поворачивает фигуру на некоторый угол

};

 

class Circle: public Figure

{

double radius;

public:

Circle(double i = 0, double j = 0, double r = 0): Figure(i, j), radius(r) { }

void draw()

{

cout << "A circle with center ";

location().print();

cout << " and radius " << radius << endl;

}

void rotate(double)

{

cout << "no effect.\n";

} // must be defined

};

 

class Square: public Figure

{

double side; // длина стороны

double angle; // угол между стороной и осью x

public:

Square(double i = 0, double j = 0, double d = 0, double a = 0)

: Figure(i, j), side(d), angle(a) { }

void draw()

{

cout << "A square with center ";

location().print();

cout << " side length " << side << ".\n"

<< "The angle between one side and the X-axis is " << angle << endl;

}

void rotate(double a)

{

angle += a;

cout << "The angle between one side and the X-axis is " << angle << endl;

}

void vertices()

{

cout << "The vertices of the square are:\n";

// вычисляем координаты вершин квадрата

}

};

 

int main()

{

Circle c(1, 2, 3);

Square s(4, 5, 6);

Figure *f = &c, &g = s;

 

f -> draw();

f -> move(Point(2, 2));

 

g.draw();

g.rotate(1);

s.vertices(); // здесь g нельзя использовать, т.к. vertices ()– не член Figure.

 

return 0;

}

 

 


Дата добавления: 2015-11-16; просмотров: 138 | Нарушение авторских прав


<== предыдущая страница | следующая страница ==>
Плата за полиморфизм| Множественное наследование

mybiblioteka.su - 2015-2024 год. (0.007 сек.)