- •Оглавление
- •1 Основные методы программирования. Лекция №2 5
- •2 Методы объектно-ориентированного программирования. Лекция №6. 15
- •2.4 Вопросы по теме 54
- •3 Объектно-ориентированное проектирование. Лекция №12 55
- •3.4 Вопросы по теме 74
- •Введение. Лекция №1.
- •1Основные методы программирования. Лекция №2
- •1.1Процедурное программирование Методы процедурного программирования
- •Этапы разработки программ. Лекция 3.
- •1.2Объектно-ориентированное программирование Лекция №4
- •Этапы разработки оо программ. Лекция №5
- •Конструкторы и деструкторы. Лекция №7.
- •Друзья класса
- •2.2Наследование. Лекция №8
- •Производный класс
- •Простое наследование
- •Множественное наследование. Лекция №9
- •Виртуальные базовые классы
- •2.3Полиморфизм. Лекция №10
- •Перегрузка операций
- •Преобразования типов, определяемые классом
- •Перегрузка функций.
- •Чистый полиморфизм
- •Виртуальные элементы-функции
- •Абстрактные классы. Лекция №11.
- •Параметрический полиморфизм
- •Шаблоны функций
- •Шаблоны классов
- •2.4Вопросы по теме
- •3Объектно-ориентированное проектирование. Лекция №12
- •3.1Концепция объектно-ориентированного проектирования
- •3.2Проектирование структурной схемы программы Составление начальной иерархии и структуры классов
- •Реорганизация иерархии и структуры классов
- •Организационная структура программы
- •3.3Проектирование файлов интерфейсов классов. Лекция № 13. Файл интерфейса базового класса
- •Файлы интерфейсов производных классов
- •Файл управления
- •3.4Вопросы по теме
- •Общие моменты разработки программы на основе объектно-ориентированного подхода
- •Приложение а
Преобразования типов, определяемые классом
Преобразование типов данных является одной их форм полиморфизма. При объектно-ориентированном программировании необходимы средства преобразований, определяемые классом (элементы-функции класса). Функциями преобразований являются: конструкторы преобразования и операции преобразования.
Конструктор преобразования - это конструктор класса с одним аргументом, служащий для преобразования из типа аргумента к типу класса.
Конструктор удобен для преобразования из базового типа в тип класса. Возьмем пример (класс complex) с перегруженной операцией +, рассмотренный выше. Пусть необходимо складывать комплексные числа с вещественными числами с получением комплексных чисел. Для этого требуется преобразование вещественного числа в комплексное число с нулевой мнимой частью. Добавим в класс complex конструктор преобразования с аргументом типа float.
Пример 3:
//файл заголовков complex3.hpp
#include <iostream.h>
#include <conio.h>
class complex
{
public:
float d,m;
complex () {d=m=0;}
complex(float x,float y) {d=x;m=y;}
complex operator +(complex& x);
complex(float x) {d=x;m=0;} //конструктор преобразования
};
//файл кодов complex3.cpp
#include "complex3.hpp"
complex complex::operator +(complex& x)
{
complex y;
y.d=d+x.d;
y.m=m+x.m;
return(y);
}
main()
{
clrscr();
complex obj1(0,1);
float a=4.5;
obj1=obj1+a; //a преобразуется из float в complex
cout<<obj1.d<<" "<<obj1.m<<'\n'; //результат: 4.5 1
getch();
}
Операция преобразования - это элемент-функция класса, осуществляющая явное преобразование типа класса в другой тип.
Операция преобразования имеет следующие свойства:
- синтаксис операции преобразования напоминает синтаксис перегруженной операции: operator tip() {...} ,где tip - идентификатор нового типа, в который происходит преобразование;
не имеет аргументов и типа возвращаемого значения;
должна быть нестатической элементом-функцией класса;
наследуется и может быть как virtual.
Операция удобна для преобразования из типа класса в базовый тип. Пусть необходимо складывать комплексные числа с вещественными числами с получением вещественных чисел. Заменим в предыдущем примере в классе complex конструктор преобразования на операцию преобразования с типом float.
Пример 4:
//файл заголовков complex4.hpp, заменим complex(float x) {d=x;
// m=0;} на operator float() {return(d);}
#include <iostream.h>
#include <conio.h>
class complex
{ //... см. complex3.hpp
operator float() {return(d);}
};
//файл кодов complex4.cpp
#include "complex4.hpp"
complex complex::operator +(complex& x)
{
complex y;
y.d=d+x.d;
y.m=m+x.m;
return(y);
}
main()
{
clrscr();
complex obj1(0,1);
float a=4.5;
float b=obj1+a; //obj1 преобразуется из типа complex в тип float
cout<<b<<'\n'; //результат: 4.5
getch();
}
Для преобразования объектов одного и того же класса используются конструкторы копирования, задаваемые явно либо по умолчанию. Пусть выполняется операция присваивания: obj2=obj1; , где obj1 и obj2 объекты одного и того же класса. В этом случае никаких преобразований типов не происходит, а выполняется только неявное поэлементное копирование.
Для преобразования объекта одного класса в объект другого класса (без наследования) используются рассмотренные выше функции преобразования: конструктор преобразования и операция преобразования. Пусть требуется преобразовать объект obj1 класса cl1 в объект obj2 класса cl2, т.е. ,например, obj2=obj1;. Тогда синтаксис функций преобразования будет иметь вид:
конструктор класса cl2: cl2::cl2(const cl1&){...}
операция класса cl1: cl1::operator cl2(){...}
Необходимо иметь одновременно только одну из этих функций преобразования, отличающихся принадлежностью классам.
Рассмотрим влияние наследования на преобразование объектов базовых и производных классов. При преобразовании объектов производного класса функции преобразования не требуется. Например, при выполнении операции присваивания происходит неявное поэлементное копирование собственной части и наследуемой (базовой) части одного объекта в другой. Пусть obj1 - объект базового класса cl1, obj2 - объект производного класса cl2. Преобразование объекта производного класса в объект базового класса допустимо без функции преобразования: obj1=obj2; ,т.е. часть объекта obj2, унаследованная от класса cl1, присваивается объекту obj1.
Преобразование объекта базового класса в объект производного класса не допустимо без функции преобразования: obj2=obj1; , это не допустимо, так как нет функции преобразования. Требуется явное преобразование из типа cl1 в тип cl2, поэтому, надо создать либо конструктор преобразования в классе cl2 (cl2::cl2 (const cl1&) {...}), либо операцию преобразования в классе cl1 (cl1::operator cl2(){...}). Теперь можно преобразование: obj2=obj1; , теперь преобразование из типа cl1 в тип cl2 допустимо.