Перегрузка операций приведения типа 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Перегрузка операций приведения типа



Преобразования типов бывают сужающими и расширяющими. Сужающие трансформируют величину в тип, который не может содержать всех значений данного типа. Расширяющие преобразования трансформируют величину в тип, который может содержать как минимум все значения исходного типа. Расширяющий тип преобразований безопасен в программировании всегда, сужающий – нет. Преобразование типов может быть как явным, так и неявным. Несмотря на отсутствие в С++ механизмов уточнения подтипов, имеется мощная поддержка перегрузки функций. При проверке соответствия учитывается преобразование типов, (переопределение), как встроенное в язык, так и определенное программистом. Принцип, лежащий в основе применяемых преобразований, состоит в том, что следует отдавать предпочтение преобразованиям наименее опасным с точки зрения возможных ошибок, наименее «сомнительным». Определенные пользователем преобразования рассматриваются только в том случае, если без них вызов разрешить нельзя.

Пример 1

void g (int);

double d = 1.234;

char *str = "Строка";

g(d); // допустимо, т.к. существует неявное преобразование double к int

G(str); // ошибка

 

Пример 2

monstr::operator int() {return health;}

monstr Vasia;

cout<<int(Vasia);


 

10.7. Правила выбора реализации перегружаемых функций в C++

Далее приведены правила выбора реализации перегружаемых функций в C++ (тип, указанный слева от стрелки, преобразуется к типу, указанному справа).

- преобразования, выполняющиеся по умолчанию

Array -> pointer

T -> const T

- стандартные преобразования

int -> double

double -> int

производный тип -> базовый

- расширяющие разрядности преобразования

int -> double

short -> int

float -> double

Формат перегрузки операции приведения типа:

operator <имя нового типа> ();

Пример 1

char c = 256; // из-за потери 8 старших битов c ='\0';

double d = 0.999999999999999999;

long n = d; // n=0;

long m = 32768; // двоичное представление числа 32768 содержит единственную единицу - в 15 разряде

int k = m; // k = -32768, т.к. 15-й разряд для int является знаковым

unsigned u = m; // m = 32768

Пример 2

void g (int);

double d = 1.234;

char *str = "Строка";

g(d); // допустимо, т.к. существует неявное преобразование double к int

G(str); // ошибка

Пример 3

monstr::operator int() {return health;}

monstr Vasia;

cout<<int(Vasia);

Переопределение операций ввода-вывода

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

Формат операций включения/исключения из потока:

ostream &operator << (ostream &out, < новый тип> < имя>)

{< тело функции оператора>};

istream &operator >> (istream &in, < новый тип> << мя>)

{< тело функции оператора>};

Если операции включения/исключения используются для полей описания, как private или protected, то эти операции должны описываться как дружественные.

Пример 1

#include<iostream.h>

Class Tadress

{

private:

char country[16];

char city[16];

char street[20];

int housenum;

public:

Tadress(){}

~Tadress(){}

friend ostream &operator << (ostream &out, Tadress obj);

friend istream &operator >> (istream &in, Tadress &obj);

};

ostream &operator << (ostream &out, Tadress obj) /* тело функции переопределяет вставки в поток */

{

out << "Address: "<< endl;

out << "Country: "<< obj.country<< endl;

out << "City:"<< obj.city<< endl;

out << "House:"<< obj.housenum<< endl;

return out;

}

istream &operator >> (istream &in, Tadress &obj) /* тело функции переопределяет исключения из потока */

{

cout<<"введите адрес следующим образом:";

cout<<" <<страна>> <<город>> <<улица>> <<номер дома>>"<<endl;

in >> obj.country >> obj.city >> obj.street >> obj.housenum;

return in;

}

Void main()

{

clrscr();

Tadress a, b;

cin >> a >> b;

cout << a << b;

getch ();

}


 



Поделиться:


Последнее изменение этой страницы: 2021-07-18; просмотров: 120; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.12.161.77 (0.006 с.)