Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Перегрузка операции приведения типаСодержание книги Похожие статьи вашей тематики
Поиск на нашем сайте
Операторные функции, осуществляющие преобразование объекта класса к другому типу, имеют формат: operator имя_нового_типа ();. Здесь, тип возвращаемого значения и параметры указывать не требуется. Для преобразований между основными типами и типами, определенными программистом используют два подхода: использование конструктора с одним аргументом при изменении основного типа на определённый пользователем и использование операции преобразования при изменении определённого пользователем типа на основной. Преобразования объектов в основные типы и наоборот Если необходимо осуществить преобразование определённых программистом типов в основные типы, то нельзя положиться на встроенные функции преобразования. В этом случае программисту необходимо самому написать функции для преобразования типов. Рассмотрим пример перевода английской меры длины в метры и обратно, в котором показано, как происходит преобразование основного типа в тип, определённый программистом, и наоборот. … const float Kmf = 3.280833; // êîýôôèöèåíò class Dist { private: int feet; float inch; public: Dist() { feet = 0; inch = 0.0; } Dist(int f, float i) { feet = f; inch = i; } Dist(float m) { //êîíñòðóêòîð ïåðåâîäà èç ìåòðîâ â ôóòû float ff = Kmf*m; feet = int(ff); inch = 12*(ff-feet); } void show() { cout << feet << "'-" << inch; } operator float() { //ìåòîä äëÿ ïåðåâîäà ÀÒÄ ê ñòàíäàðòíîìó float float fut = inch/12; //d1.inch fut = fut + float(feet); //d1.feet return fut/Kmf; } }; //--------------------------------------------------------------------------- int main() { Dist d1; float metr = 2.35, metr2=0.0; d1 = Dist(metr); //переводим float в Dist cout << "\nd1 = "; d1.show(); //увидим d1=7'-8.51949 metr2 = float(d1); //переводим Dist во float (можно написать просто metr2 = d1; ) cout << "\nmetr2 = " << metr2; //увидим metr2=2.35 getch(); return 0; } Для перехода от основного типа float к определённому программистом типу Dist мы используем конструктор с одним аргументом Dist(float m)…. Такого рода конструкторы иногда называют конструкторами преобразования. Этот конструктор вызывается, когда создаётся объект класса Dist с одним аргументом. Для перехода от определённого программистом типа Dist к основному типу float (в данной программе) используется метод преобразования. Этот метод принимает значение объекта класса Dist, преобразовывает его в значение типа float, представляющее собой метры, и возвращает это значение.
Преобразование объектов классов в объекты других классов При преобразовании объектов одного класса в объекты другого класса применяются те же два способа преобразования, что и для преобразований между основными типами и объектами определённых пользователем классов, т.е. используется конструктор с одним аргументом или операция преобразования. Выбор зависит от того, хотите ли вы записать функцию преобразования в классе для исходного объекта или для объекта назначения. Если процедура преобразования записана в классе назначения, то используется конструктор, если процедура в исходном классе, то применяется операция преобразования. Класс назначения - это класс, объект которого получает значение. Например, записано object_a=object_b;, где object_a – объект класса А (это класс назначения), а object_b – объект класса В. Рассмотрим программу, в которой производятся преобразования между двумя способами исчисления времени: 12-часовым и 24-часовым. На этом примере рассмотрим случай, когда функция преобразования расположена в исходном классе, следовательно исходя из упомянутого выше правила реализуем преобразование объекта одного класса в объект другого класса в виде операции (метода) преобразования. class Time12 { private: bool pm; int hrs; int mins; public: Time12(): pm(true), hrs(0), mins(0) { } Time12(bool ap, int h, int m): pm(ap), hrs(h), mins(m) { } void display() const { cout << hrs << ':'; if (mins < 10) cout << '0'; cout << mins << ' '; string am_pm = pm? "p.m.": "a.m."; cout << am_pm; } }; //--------------------------------------------------------------------------- class Time24 { private: int hours; int minutes; int seconds; public: Time24(): hours(0), minutes(0), seconds(0) { } Time24(int h, int m, int s): hours(h), minutes(m), seconds(s) { } void display() const { if (hours < 10) cout << '0'; cout << hours << ':'; if (minutes < 10) cout << '0'; cout << minutes << ':'; if (seconds < 10) cout << '0'; cout << seconds; } operator Time12() const; }; //--------------------------------------------------------------------------- Time24::operator Time12() const { int hrs24 = hours; bool pm = hours < 12? false: true; int roundMins = seconds < 30? minutes: minutes + 1; if (roundMins == 60) { roundMins = 0; ++hrs24; if (hrs24 == 12 || hrs24 == 24) pm = (pm == true)? false: true; } int hrs12 = (hrs24 < 13)? hrs24: (hrs24 - 12); if (hrs12 == 0) { hrs12 = 12; pm = false; } return Time12(pm, hrs12, roundMins); } //--------------------------------------------------------------------------- int main() { int h, m, s;
while (true) { cout << "Vvedite vremja v 24 formate: \n"; cout << " Chasy (от 0 до 23): "; cin >> h; if (h > 23) return (1); cout << " Min: "; cin >> m; cout << " Sek: "; cin >> s;
Time24 t24(h, m, s); // присвоили объекту значения, введенные с клав. cout << "Ishodnoe vremja: "; t24.display();
Time12 t12 = t24; // преобразование
cout << "\nV 12-chas formate: "; t12.display(); cout << "\n\n"; } return 0; } //---------------------------------------------------- Функция Time24::operator Time12() const преобразует вызывающий её объект t24 в объект класса Time12 и возвращает его в главную функцию. Если функция преобразования находится в классе назначения, то необходимо использовать конструктор с одним аргументом. В этом случае мы должны были в классе Time12 написать конструктор с 1 аргументом Time12(Time24) и метод Time12::Time12(Time24 t24).
Лекция 7 (15 стр.) НАСЛЕДОВАНИЕ Наследование – это процесс создания новых классов, называемых наследниками или производными классами, из уже существующих или базовых классов. Производный класс получает все возможности базового класса и может быть усовершенствован за счёт добавления собственных. Базовый класс при этом остаётся неизменным. Проиллюстрируем взаимосвязь классов при наследовании.
Наследование позволяет использовать существующий код несколько раз. Важным результатом повторного использования кода является упрощение распространения библиотек классов. На одном из прошлых занятий мы разбирали класс Count, в котором использовалась перегруженная операция ++. Допустим теперь нам необходимо, не изменяя этот класс, создать метод для уменьшения счётчика. Допустим на создание и тестирование класса Count было затрачено много времени и желание его не изменять вполне очевидно. Или мы просто не имеем доступа к исходному коду класса, например, если он распространяется как часть библиотеки классов. В этих случаях целесообразно использовать наследование для создания производных классов. class Count { //áàçîâûé êëàññ protected: int c; public: Count() { c=0; } Count(int t) { c=t; } int get() const { return c; } Count operator++() { ++c; return Count(c); } }; //--------------------------------------------------------------------------- class CountPr: public Count { // ïðîèçâîäíûé êëàññ public: Count operator--() { --c; return Count(c); } }; //--------------------------------------------------------------------------- int main() { CountPr c1; // îáúåêò ñ1 ïðîèçâîäíîãî êëàññà cout << "\n c1=" << c1.get(); ++c1; ++c1; ++c1; cout << "\n c1=" << c1.get(); --c1; --c1; cout << "\n c1=" << c1.get(); getch(); return 0; } В данной программе определён новый производный класс CountPr, который включает в себя новый метод уменьшения счётчика и в тоже время наследует (использует) все возможности базового класса Count (его конструкторы и методы). Строка class CountPr: public Count определяет, что класс CountPr является наследником базового класса. Ключевое слово public определяет, что объект производного класса может иметь доступ к методам базового класса, объявленным как public. Если используется ключевое слово private, то для объектов производного класса нет доступа к членам базового класса. При создании объекта с1 производного класса происходит его инициализация нулевым значением несмотря на то, что в классе CountPr нет конструктора. Здесь работает принцип – если конструктор производного класса не определён, то будет использоваться подходящий конструктор базового класса. В данном случае используется конструктор без аргументов базового класса Count. Таким образом, использование доступного метода взамен отсутствующего – обычная ситуация, возникающая при наследовании. Действительно, объект с1 класса CountPr, не находя методы в своём классе, использует необходимые методы из базового класса. Вывод программы: С1=0 С1=3 С1=1 В данной программе переменная c имеет спецификатор доступа protected. Рассмотрим его предназначение. Методы производного класса имеют доступ к членам (полям и методам) базового класса, если последние имеют спецификатор доступа public или protected. К членам, объявленным как private, доступа нет. Если бы поле count было бы объявлено как public, то это разрешило бы доступ к переменной c из любой функции программы, уничтожив тем самым возможность сокрытия данных. Таким образом, член, объявленный как protected, доступен методам своего класса и методам любого производного класса, но при этом он не будет доступным из функций, не принадлежащих этим классам, например из функции main(). Приведём таблицу, отражающую возможности использования спецификаторов доступа в различных ситуациях.
Таблица 1. Наследование и доступ
Таким образом, если создаётся класс, который впоследствии будет использоваться как базовый класс при наследовании, то данные, к которым необходимо иметь доступ из производного класса, следует объявлять как protected. Необходимо помнить, что наследование не работает в обратном направлении. Базовому классу и его объектам недоступны производные классы. То есть, если создать объект с2 класса Count, то он не сможет использовать метод operator--() класса CountPr, а объект производного класса может использовать все методы, как базового класса, так и производного.
|
||||||||||||||||||||||||||
Последнее изменение этой страницы: 2016-04-08; просмотров: 747; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.116.14.48 (0.01 с.) |