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

Когда виртуальные функции вызываются из производного класса, но не замещаются, то вызывается функция базисного класса. Но в почти всех случа­ях нет смыслового определения виртуальной функции в базисном классе. Напри­мер, в базисном классе Figure примера 33 для функции show_area() использу­ется просто "заглушка" с сообщением. При разработке библиотеки классов Чистые виртуальные функции и абстрактные классы для виртуальных функций еще непонятно, будет ли смысловое содержание в контексте базисного класса. Существует два метода совладать с этой пробле­мой.

1-ый — выдать предупреждающее сообщение. Но это полезно не во всех случаях. К примеру, может быть виртуальная функция, которая должна быть определена в производном классе, и иметь некое значение Чистые виртуальные функции и абстрактные классы. В классе Figure площадь в общем случае не определена.

Другим решением этой препядствия в С++ являются незапятнанные виртуальныефункции (pure) – это функции объявленные в базисном классе как виртуальные, но не имеющие описания. Производный класс должен найти свою соб­ственную версию виртуальной функции, потому что нельзя просто использовать версию базисного класса. По Чистые виртуальные функции и абстрактные классы другому говоря, незапятнанная виртуальнаяфункция – это пу­стое место, ожидающее собственного наполнения производным классом. Объявляется незапятнанная виртуальная функция, как и рядовая виртуальная, но заканчивается =0.

К примеру, в классе:

class AbstractClass

{ public:

virtual void f1 (); // виртуальная функция

virtual void f2 () = 0; // незапятнанная виртуальная функция

};

Компилятору не будет нужно реализация функции f2, в отличие от осталь­ных Чистые виртуальные функции и абстрактные классы функций, так как она не содержит собственного тела.

Если класс содержит хотябы одну чистую виртуальную функцию, он на­зывается абстрактным классом (abstract class). Подобно хоть какой абстрактной идее, абстрактный класс обрисовывает нереализованные концепции.

Абстрактный класс имет одну важную черту – нельзя сделать объектэтого класса. К примеру, нельзя объявить объект Чистые виртуальные функции и абстрактные классы типа AbstractClass, по другому компилятор выдаст ошибку. Причина, по которой абстрактные классы не могут употребляться для объявления объекта та, что одна либо более функций не име­ют определения.

Это всего только схема, на базе которой можно со­здать производный класс. Он должен употребляться только как интерфейс и в качестве Чистые виртуальные функции и абстрактные классы базисного класса, от которого наследуются другие классы. По другому говоря, абстрактный класс представляет собой интерфейс к огромному количеству реализаций общего понятия. Естественно, другие функции-элементы класса AbstractClass могут вызывать чистую вирту­альную функцию. К примеру, функция f1 может вызвать f2:

void AbstractClass :: f1()

{ f2 (); // вызвать чистую виртуальную функцию

. . .

}

Чтоб использовать абстрактный Чистые виртуальные функции и абстрактные классы класс, следует вывести из него новый класс:

class Myclass : public AbstractClass

{ public:

virtual void f2 (); // бывшая незапятнанная виртуальная функция

. . .

}

Производный класс Myclass наследует чистую виртуальную функцию, но заявляет ее без =0. В другом месте следует воплотить функцию-элемент f2:

void Myclass :: f2 ()

{ . . . // операторы функции-элемента

}

Воззвания к начальной незапятанной виртуальной Чистые виртуальные функции и абстрактные классы функции-элементу, например, в этом случае AbstractClass:: f1(), сейчас преадресованы Myclass :: f2(). Незапятнанные виртуальные функции подобны крючкам, на которые вы сможете цеплять код производных классов. Сейчас, когда все виртуальные функции-эле­менты реализованы, компилятор сумеет воспринять объекты типа Myclass:

Myclass myobject;

Выполнение оператора myobject.f1 приведет к вызову наследо­ванной функции Чистые виртуальные функции и абстрактные классы f1, которая и вызовет f2 из Myclass.

Абстрактный класс не может быть применен как тип аргумента и функции show_area(). В главной функции из объявления: Figure f, *p; нужно уда­лить объект f и три строчки операторов с ним связанных, по другому компилятор ука­жет на ошибку сотворения объекта Чистые виртуальные функции и абстрактные классы абстрактного типа.

Результаты программки:

Треугольник с высотой 3 и основанием 4 имеет площадь = 6

Прямогольник со сторонами 5 и 6 имеет площадь = 30

Круг с радиусом 2 имеет площадь = 12.56

Производные классы с конструкторами и деструкторами

Каждый класс — базисный и производный может иметь конструктор и де­структонкция

virtual void draw()=0; // незапятнанная виртуальная функция

} shape x; // ошибка: попытка сотворения объекта

// абстрактного класса

shape f Чистые виртуальные функции и абстрактные классы(); // ошибка: абстрактный класс не может быть

// типом возврата

int q(shape s); // ошибка: абстрактный класс не может быть

// типом аргумента функции

shape* sp; // указатель на абстрактный класс допустим

shape& h(shape&); // ссылка на абстрактный класс в качестве типа

// возврата либо аргумента функции допустима

Представим, что В является производным классом от абстрактного ба­зового класса А Чистые виртуальные функции и абстрактные классы. Тогда для каждой незапятанной виртуальной функции fun() в А класс В должен обеспечивать определение fun, или объявлять fun как чисто вирту­альную функцию. Если этого не изготовлено, то компилятор скажет об ошибке. К примеру, описание производного класса от Shape с замещением чисто виртуальных функций:

class Circle: public Shape Чистые виртуальные функции и абстрактные классы // производный класс

{ int radius;

public:

virtual void rotate(int) { } // деяния отсутствуют

void draw (); // замещение Shape:: draw

};

Circle c;

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

Чисто виртуальная функция, которая не определена в производном клас­се, остается чисто виртуальной, потому таковой производный класс, как и базо­вый, является абстрактным. Это позволяет строить реализацию поэтапно:

class Poligon: public Shape // новый абстрактный класс

{ public:

void Чистые виртуальные функции и абстрактные классы rotate(int); // замещение Shape:: rotate

// draw не замещен

};

Poligon p; // ошибка: объявление объекта абстрактного класса

class Newpoligon: public Poligon // производный класс

{ public:

void rotate(int); // замещение Shape:: rotate

void draw (); // замещение Shape::draw

};

Newpoligon np; // верно

Пример 35.

Разглядим измененную версию программки примера 33. В классе Figure функцию show_area() определим как чистую виртуальную:

class Figure // базисный класс

{ protected: // защищенные Чистые виртуальные функции и абстрактные классы элементы, доступные в производных классах

double x, y;

public:

void set_dim (double i, doublej=0) // 2-й параметр по дефлоту

{ x = i, y = j; } // задание измерений фигур

virtual void show_area() = 0; // незапятнанная виртуальная функция

};

В производных классах остаются переопределенные функции show_area(). В главной функции из объявления: Figure f, *p; нужно уда­лить объект Чистые виртуальные функции и абстрактные классы f и три строчки операторов с ним связанных, по другому компилятор ука­жет на ошибку сотворения объекта абстрактного типа.

Результаты программки:

Треугольник с высотой 3 и основанием 4 имеет площадь = 6

Прямогольник со сторонами 5 и 6 имеет площадь = 30

Круг с радиусом 2 имеет площадь = 12.56


chistaya-monopoliya-cenovaya-diskriminaciya.html
chistaya-pravda-o-detektore-lzhi-referat.html
chistaya-pribil-rastet-do-teh-por-poka-novaya-tovarnaya-produkciya-konkurentosposobna-i-polzuetsya-sprosom-u-pokupatelej.html