Logo Море(!) аналитической информации!
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

VPS в России, Европе и США

Бесплатная поддержка и администрирование

Оплата российскими и международными картами

🔥 VPS до 5.7 ГГц под любые задачи с AntiDDoS в 7 локациях

💸 Гифткод CITFORUM (250р на баланс) и попробуйте уже сейчас!

🛒 Скидка 15% на первый платеж (в течение 24ч)

Скидка до 20% на услуги дата-центра. Аренда серверной стойки. Colocation от 1U!

Миграция в облако #SotelCloud. Виртуальный сервер в облаке. Выбрать конфигурацию на сайте!

Виртуальная АТС для вашего бизнеса. Приветственные бонусы для новых клиентов!

Виртуальные VPS серверы в РФ и ЕС

Dedicated серверы в РФ и ЕС

По промокоду CITFORUM скидка 30% на заказ VPS\VDS

5.5.5. Выбор методов для операций

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

Методы, выбор которых возможен во время компиляции, на языке C могут быть реализованы как непосредственные вызовы соответствующих функций. Это прежде всего относится к тем операциям, которые реализуются только одним методом, что снимает проблему выбора. Например, все методы в классе Window уникальны (единственны). Однако наиболее общий подход состоит в определении для каждого класса дескриптора, содержащего указатели на все методы для каждой операции, видимой из этого класса, включая унаследованные операции. Каждый дескриптор класса является структурой языка C, элементами которой являются все операции, определенные в этом классе или унаследованные им от суперкласса. Следующий фрагмент программы содержит определения дескрипторов класса для классов Item, Shape, Box и Circle:


	struct ItemClass

	{

	char* class_name;

	void(* cut)();

	void(* move)();

	Boolean(* pick)();

	void(* ungroup)();

	};

	struct ShapeClass

	{

	char* class_name;

	void(* cut)();

	void(* move)();

	Boolean(* pick)();

	void(* ungroup)();

	void(* write)();

	};

	struct BoxClass

	{

	char* class_name;

	void(* cut)();

	void(* move)();

	Boolean(* pick)();

	void(* ungroup)();

	void(* write)();

	};

	struct CircleClass

	{

	char* class_name;

	void(* cut)();

	void(* move)();

	Boolean(* pick)();

	void(* ungroup)();

	void(* write)();

	};

В дескрипторе класса определены операции, видимые в этом классе, но остается необходимость определить и проинициализировать дескрипторы класса для каждого класса: в каждом поле дескриптора класса должно стоять имя функции, которая реализует метод, определенный в этом классе или унаследованный им (например, класс Box наследует операцию move у класса Shape, но заменяет операции pick и write своими собственными методами:


	struct BoxClass BoxClass =

	{

	"Box",

	Shape__cut,

	Shape__move,

	Box__pick,

	Shape__ungroup,

	Box__write,

	};

	struct CircleClass CircleClass =

	{

	"Circle",

	Shape__cut,

	Shape__move,

	Circle__pick,

	Shape__ungroup,

	Circle__write,

	};

Если у класса есть атрибуты уровня класса, их тоже можно запомнить в дополнительных полях дескриптора класса. Например, можно поместить в дескриптор класса имя этого класса и использовать его во время отладки, или каким-либо другим образом.

Отметим, что дескриптор класса не нужен абстрактному классу (например, Shape). Когда порождается новый объект, указатель на его дескриптор класса помещается в поле Class структуры, представляющей этот объект:


	struct Circle * create_circle(x0,y0,radius0)

	Length x0,y0,radius0;

	{

	struct Circle * new_circle;

	new_circle =

	(struct Circle*)malloc(sizeof(struct Circle));

	new_circle->class = &CircleClass;

	new_circle->x = x0;

	new_circle->y = y0;

	new_circle-> radius = radius0;

	return new_circle;

	};

Если выбор метода для операции должен быть сделан во время выполнения программы, то для определения нужной функции используется дескриптор класса. Например, вызов операции pick для формы (Shape), определяемой во время выполнения программы, требует следующего кода:


	struct Shape* shape;

	Length x,y;

	Boolean status;

	status = (*shape->class->pick)(shape,x,y);

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

Назад | Содержание | Вперед

VPS/VDS серверы. 30 локаций на выбор

Серверы VPS/VDS с большим диском

Хорошие условия для реселлеров

4VPS.SU - VPS в 17-ти странах

2Gbit/s безлимит

Современное железо!

Бесплатный конструктор сайтов и Landing Page

Хостинг с DDoS защитой от 2.5$ + Бесплатный SSL и Домен

SSD VPS в Нидерландах под различные задачи от 2.6$

✅ Дешевый VPS-хостинг на AMD EPYC: 1vCore, 3GB DDR4, 15GB NVMe всего за €3,50!

🔥 Anti-DDoS защита 12 Тбит/с!

Новости мира IT:

Архив новостей

IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

Информация для рекламодателей PR-акции, размещение рекламы — adv@citforum.ru,
тел. +7 495 7861149
Пресс-релизы — pr@citforum.ru
Обратная связь
Информация для авторов
Rambler's Top100 TopList This Web server launched on February 24, 1997
Copyright © 1997-2000 CIT, © 2001-2019 CIT Forum
Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...