240-1677 (Объективное программирование), страница 5

2016-07-31СтудИзба

Описание файла

Документ из архива "Объективное программирование", который расположен в категории "". Всё это находится в предмете "информатика" из , которые можно найти в файловом архиве . Не смотря на прямую связь этого архива с , его также можно найти и в других разделах. Архив можно найти в разделе "рефераты, доклады и презентации", в предмете "информатика, программирование" в общих файлах.

Онлайн просмотр документа "240-1677"

Текст 5 страницы из документа "240-1677"

class : ,,...

{

определение приватной и публичной части

производного класса

}

Перечислим основные свойства базового и производного классов:

- объект базового класса определяется в производном классе как неименованный. Это значит, что он не может быть использован в явном виде как обычный именованный объект;

- элементы данных базового класса включаются в объект производного класса (как правило, компилятор размещает их в начале объекта производного класса). Oднако приватная часть базового класса закрыта для прямого использования в производном классе;

- элементы-функции базового класса "наследуются" в производном классе, то есть вызов функции, определенной в базовом классе, для объекта производного класса возможен и понимается как вызов ее для входящего в него объекта базового класса;

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

Пример схемы определения производного класса

class a

{

public:

void f() {}

void g() {}

}

class b : a ------------------------ базовый класс

{

public: void f() -------------------- "f" переопределяется

{ ...

a::f(); -------------- явный вызов "f" для БК

} -------------- "g" наследуется из БК

void h() {} -------------- собственная функция в ПК

}

void main()

{

a A1;

b B1;

B1.f(); --------------- вызов переопределенной b::f()

B1.g(); --------------- вызов наследуемой a::f()

}

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

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

Взаимоотношение конструкторов и деструкторов базового и производного классов аналогичны выше описанным:

- если конструктор производного класса определен обычным образом, то сначала вызывается конструктор базового класса без параметров, а затем конструктор производного класса. Деструкторы

вызываются в обратном порядке - сначала для производного, затем

для базового;

- в заголовке конструктора производного класса может быть

явно указан вызов конструктора базового класса с параметрами. Он

может быть без имени, а может быть с именем базового класса. Если

производный класс включает в себя объекты нескольких базовых

классов, то в вызовы конструкторов базовых классов должны быть

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

6.3 Права доступа в производных классах

--------------------------------------

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

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

так и извне - через объекты производного класса. Здесь возможны

следующие варианты:

- приватная часть базового класса A всегда включается в приватную часть производного класса B, но при этом непосредственно

недоступна из элементовфункций класса B. Это соответствует тому

факту, что в классе B разрешается работать с базовым объектом

класса A только разрешенными в классе A средствами, то есть через элементы-функции класса A. Исключение составляет объявление всего класса B дружественным в классе A;

- по умолчанию, то есть при использовании заголовка вида

class B : A { }

публичная часть класса A попадает в приватную часть класса B. Это значит, что элементы-функции класса A доступны из элементов-функций класса B, но не могут быть вызваны извне, то есть при обращении к объектам класса B. То есть для внешнего пользователя класса B интерфейс класса A закрывается;

- в противном случае, при объявлении

class B : public A { }

публичная часть класса A попадает в публичную часть класса B, и внешний пользователь при работе с объектами класса B может применить интерфейсы как производного, так и базового классов;

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

class B : A {

...

public:

...

public A::fun;

...

}

Перечисленные варианты изображены на схеме:

class A class B

-----------¬ ----------------¬

¦ privat ======================> privat A ¦

+----------+ ¦ (недоступен B)¦

¦ public ¦ class B:A +---------------+

¦ ======================> privat B ¦

¦ ¦ ¦ (доступен B) ¦

¦ ¦ class B : public A ¦===============¦

¦ ======================> public B ¦

¦ ¦ class B : A { ... ¦ ¦

¦ ¦ public A::newadr; ¦ <---- Доступ к объектам

¦ ----------------------> производного класса

L----------- L---------------

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

аналогии с дружественностью базовый класс может разрешить доступ

к своим элементам личной части в производных классах. Это делается при помощи объявления защищенных (protected) элементов.

Элемент с меткой protected в базовом классе входит в приватную часть базового класса. Кроме того, он доступен и в приватной

части производного класса. Если же базовый класс включается в

производный как public, то защищенный элемент становится защищенным и в производном классе, то есть может использоваться в последующих производных классах. Сказанное поясним примером и схемой:

class A

{

int a1; // Обычный приватный элемент

protected: int a2; // Защищенный приватный элемент

public:

}

class B : A // a1,a2 в приватной части B

{

void x();

}

void B::x()

{

a1 = 5; // Ошибка: a1 недоступен в B

a2 = 3; // a2 доступен в приватной части B

}

class B : public A // a2 доступен и защищен в приватной

{ // части B, неявно имеет место

// protected: int a2;

}

class A class B

-----------¬ ----------------¬

¦ privat ======================> privat A ¦

+----------+ ¦ (недоступен B)¦

¦ protected¦ class B:A +---------------+

¦ ======================> privat B ¦

¦ ===============¬ ¦ (доступен B) ¦

+----------+ class B: public A +---------------+

¦ public ¦ L======> protected B ==========>

¦ ¦ ¦===============¦

¦ ¦ ¦ public ¦

6.4 Ссылки на объекты базового и производного классов

----------------------------------------------------

Из классического Си известно, что путем присваивания ссылкам различного типа одного и того же значения (адреса) можно работать с общей памятью как с различными структурами данных. При этом преобразование типа и присваивание не меняют значения ссылки, то есть адреса памяти.

Применительно к базовому и производному классу можно сказать, что, преобразуя ссылку на объект производного класса к ссылке на объект базового класса, мы получаем доступ к вложенному объекту базового класса. Но при таком трактовании преобразования типа ссылки транслятору необходимо учитывать размещение объекта базового класса в производном, что он и делает. В результате при таком преобразовании (присваивании) значение ссылки (адрес памяти) может оказаться не равным исходному. Ввиду того, что такой переход от объекта производного класса к базовому часто встречается и корректируется транслятором, это преобразование типа ссылки в Си++ может бытьл выполнено неявно (остальные преобразования

типов ссылок должны быть явнями)

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

class A

{

public: void f1();

};

class B : A

{

public: void f1(); // Переопределена в классe B

void f2(); //

};

A *pa;

B *pb;

B x;

pa = &x; // Неявное преобразование ссылки

// на объект класса B в ссылку

// на объект класса A

pa->f1(); // Вызов функции из вложенного

// объекта базового класса A::f1(),

// хотя она переопределена

Обратное преобразование от ссылки на базовый класс к ссылке

на производный может быть сделано только явно. При этом корректность такого преобразования зависит от программы:

pb = (B*) pa; // Обратное преобразование - явное

pb ->f2(); // Корректно, если под "pa" был

// объект класса "B"

6.5 Принцип объектно-ориентированного программирования

------------------------------------------------------

Понятие производного класса является основой объектноориенированного подхода к программированию, которое можно определить

как программирование "от класса к классу". Традиционное программирование "от функции к функции" предполагает, что вновь разрабатываемые структуры данных включают в себя определенные ранее, а

новые функции включают вызовы ранее определенных.

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

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

и добавляет новые. В принципе ничто не препятствует на любом

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

классов. Следование же технологии объектно-ориентированного программирования "до конца" предполагает, что прикладная программа

представляет собой класс самого верхнего уровня, в ее выполнение

- создание объекта этого класса или выполнение для него некоторой функции типа "run".

Лекция 7. Виртуальные функции.

-----------------------------

7.1 Понятие виртуальной функции

------------------------------

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

p[] A1

+---+ -b---------¬

¦ --------------------->-a-------¬¦======== b::f()

+---+ ¦L---------¦===¬

¦ ------------¬ L----------- ¦

+---+ ¦ C1 ¦

¦ ----------¬ ¦ -c---------¬ ¦

+---+ ¦ L-------->-a-------¬¦======== c::f()

¦ ¦L---------¦===¦

¦ L----------- ¦

¦ A1 ¦

L---------->-a-------¬ ===¦==== a::f()

L--------

class a

{ ... void f(); };

class b : public a

{ ... void f(); };

class c : public a

{ ... void f(); };

a A1;

b B1;

c C1;

a *p[3]; // Массив ссылок на объекты БК

p[0] = &B1; // Ссылки на объекты БК в

p[1] = &C1; // объектах ПК

p[2] = &A1;

Однако при таком преобразовании типа "ссылка на объект ПК" к

типу "ссылка на объект БК" происходит потеря информации о том,

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

есть

p[0]->f(); // Вызов a::f()

p[1]->f(); // во всех случаях, хотя f()

p[2]->f(); // переопределены

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

- хранить в объекте базового класса идентификатор "окружающего" его производного класса;

- в списке или таблице хранить ссылки на объект базового

класса;

- при вызове функции по ссылке на объект базового класса

идентифицировать тип производного класса и явно вызывать для него

переопределенную функцию;

- идентификатор класса устанавливать при создании объекта ,

то есть в его конструкторе.

class a

{

public: int id; // Идентификатор класса

Свежие статьи
Популярно сейчас
Почему делать на заказ в разы дороже, чем купить готовую учебную работу на СтудИзбе? Наши учебные работы продаются каждый год, тогда как большинство заказов выполняются с нуля. Найдите подходящий учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
5167
Авторов
на СтудИзбе
438
Средний доход
с одного платного файла
Обучение Подробнее