Навигация
Главная
Поиск
Форум
FAQ's
Ссылки
Карта сайта
Чат программистов

Статьи
-Delphi
-C/C++
-Turbo Pascal
-Assembler
-Java/JS
-PHP
-Perl
-DHTML
-Prolog
-GPSS
-Сайтостроительство
-CMS: PHP Fusion
-Инвестирование

Файлы
-Для программистов
-Компонеты для Delphi
-Исходники на Delphi
-Исходники на C/C++
-Книги по Delphi
-Книги по С/С++
-Книги по JAVA/JS
-Книги по Basic/VB/.NET
-Книги по PHP/MySQL
-Книги по Assembler
-PHP Fusion MOD'ы
-by Kest
Professional Download System
Реклама
Услуги

Автоматическое добавление статей на сайты на Wordpress, Joomla, DLE
Заказать продвижение сайта
Программа для рисования блок-схем
Инженерный калькулятор онлайн
Таблица сложения онлайн
Популярные статьи
OpenGL и Delphi... 65535
Форум на вашем ... 65535
21 ошибка прогр... 65535
HACK F.A.Q 65535
Бип из системно... 65535
Гостевая книга ... 65535
Invision Power ... 65535
Пример работы с... 65535
Содержание сайт... 65535
ТЕХНОЛОГИИ ДОСТ... 65535
Организация зап... 65535
Вызов хранимых ... 65535
Создание отчето... 65535
Имитационное мо... 65535
Программируемая... 65535
Эмулятор микроп... 65535
Подключение Mic... 65535
Создание потоко... 65535
Приложение «Про... 65535
Оператор выбора... 65535
Реклама
Сейчас на сайте
Гостей: 9
На сайте нет зарегистрированных пользователей

Пользователей: 13,372
новичок: vausoz
Новости
Реклама
Выполняем курсовые и лабораторные по разным языкам программирования
Подробнее - курсовые и лабораторные на заказ
Delphi, Turbo Pascal, Assembler, C, C++, C#, Visual Basic, Java, GPSS, Prolog, 3D MAX, Компас 3D
Заказать программу для Windows Mobile, Symbian

Моделирование процесса поступления заявок в систему, состоящую из трёх Э...
Моделирование ЭВМ на GPSS (три класса заданий) + Пояснительная записка
Игра Sokoban на Delphi + Блок схемы

Функции приведения


Язык C++ позволяет выполнять преобразование значения одного типа в значение другого типа. Преобразование типа бывает явным и неявным. Явное преобразование называется приведением типов. При приведении типов перед преобразовываемой переменной в скобках указывается имя типа, к которому она приводится. Например:

int iVar;
float fVar;
fVar = 10*(float)iVar; /*перед умножением выполняется приведение типа int переменной iVar к типу float, однако тип переменной iVar после вычисления выражения останется неизменным, т.е. int*/




Преобразование типов выполняется для значений переменных при вычислении выражений и оказывает влияние на тип результата, но не изменяет типа самих переменных, участвующих в выражении. Преобразование типов между базовыми типами и преобразование типа для указателей, ссылок и указателей на члены производного типа называется стандартным преобразованием типов. В языке C++ автоматически выполняется стандартное преобразование типов в том случае, если выражение содержит переменные различных типов.
Основные правила для автоматического преобразования типов состоят в следующем:
• - типы всех переменных, используемых в выражении справа от оператора присваивания, сначала преобразовываются к наиболее «широкому» типу, а затем выполняется вычисление выражения;
• - тип результата будет преобразован к типу значения, расположенного слева от оператора присваивания.
При преобразовании типов char и int, а также типов, образуемых из них (таких как short, long, signed и unsigned), выполняются следующие правила:
• - при преобразовании целого типа signed к типу unsigned не про-исходит изменения значения битов и поэтому для отрицательных чисел значение переменной типа unsigned будет отличаться от значения переменной типа signed. Например:
short s = -3;
unsigned short us;
us = i; //переменная us будет равна 65533



• - при преобразовании целого типа unsigned к типу signed не происходит изменения значения битов и поэтому значения переменной типа unsigned могут отличаться от значения переменной типа signed. Например:
short s;
unsigned short us = 65533;
i = us; //переменная i будет равна -3



• - допускается автоматическое преобразование целого типа к более «короткому» типу, однако это может вызвать потерю части данных.
При преобразовании типов с плавающей точкой выполняются следующие правила:
• - допускается автоматическое преобразование типа float к
double и double к long double, значение переменной при этом не изменяется;
• - преобразование к более «короткому» типу с плавающей точкой (например, double к float) происходит корректно только в том случае, если нет потери значения, в противном случае результат будет неопределен;
• - преобразование типа с плавающей точкой к целому типу приводит к усечению дробной части (например, 3.5 преобразуется к 3).
Для арифметических выражений используются следующие правила преобразования типов, приведенные в табл. 3:

Таблица 3 Правила преобразования типов


Преобразование типа указателя может происходить при инициализации, присвоении, сравнении и других операциях.
Целое константное выражение, равное нулю, или выражение, приводимое к типу void*, преобразовывается к указателю, называемому
NULL-указателем. Такой указатель может использоваться для сравнения и оп-ределения существования объекта.
Указатель типа void* может быть преобразован к указателю любого другого типа только явным приведением типа. Обратно, указатель любого типа может быть неявно преобразован к указателю типа void*.
Это может быть использовано для передачи параметров функции, для которой формальный параметр может быть указателем различных типов, например int* или float*. В этом случае прототип функции будет выглядеть следующим образом:
void F1(void *pVar);



а вызов функции будет выполняться как:
int *piVar;
float *pfVar;
F1(piVar);
F1(pfVar);



В теле функции для работы с указателем надо будет использовать явное преобразование типа, например (int*) piVar.
Указатель на любой объект, не являющийся const или volatile, может быть неявно преобразован к указателю типа void*.
Указатель на функцию может быть преобразован к типу void*, если тип void* является достаточным для размещения этого указателя.
Указатель на класс может быть преобразован к указателю на базовый класс в том случае, если:
• - специфицируемый базовый класс является доступным и преобра-зование является недвусмысленным;
• - используется явное преобразование типа указателя (результатом этого является указатель на «подобъект» - часть объекта, описанная в базовом классе). Например:

class A

{

public:

int AComponent;

int AMemberF();

};



class B: public A

{

public:

int BComponent;

int BMemberF();

};



B bObject; //объект класса B

A *pA = &bObject; /*этот указатель ограничивает дос-туп к членам класса B:
BComponent и BMemberF() и допуска-ет только доступ к членам базового класса*/

B *pB = &bObject; /*разрешен доступ как к членам класса B, так и к членам класса
A*/

pA->AMemberF();//разрешено: функция-член класса A

pB->AMemberF();//разрешено: наследуется от класса A

pA->BMemberF();//ошибка: нет в классе A






Любое выражение, имеющее тип массива, может быть преобразовано к указателю того же типа. Результатом будет указатель на первый элемент масси-ва. Например:

char Path[MAX_PATH]; //массив типа char*
char *pPath = Path; //указатель на массив,
//эквивалентно &Path[0]

C++ не поддерживает стандартное преобразование данных типа const или volatile к любому типу, не являющемуся также const или volatile. Однако это может быть выполнено посредством явного приведения типов.
Отметим, что указатели на члены (класса, структуры) не могут рассмат-риваться как обычные указатели (в отличие от указателей на статические чле-ны) и для них не выполняется стандартное преобразование.
Вы можете определить функции-элементы, которые будут осуществлять явное преобразование типа класса к другому типу. Эти функции называют опе-раторами приведения или процедурами преобразования типа. Они имеют следующий вид:
operator имя_нового_типа();




Процедуры преобразования подчиняются следующим правилам:
• - процедура преобразования не имеет аргументов;
• - процедура преобразования не имеет явной спецификации типа возвращаемого значения, так как подразумевается тип, указанный после ключевого слова operator;
• - процедура преобразования может описываться как virtual;
• - процедура преобразования наследуется.
С одной стороны, легко предотвратить выполнение операции преобразо-вания, просто не определив этой операции. С другой – может потребоваться сконструировать объекты с использованием одного значения другого типа так, чтобы не осуществлялось скрытое преобразование с помощью конструктора с одним аргументом. В стандарт языка C++ включено ключевое слово explicit, предназначенное для решения этой проблемы. Оно просто помещается перед объявлением конструктора с одним аргументом. В результате чего конструктор, объявленный с ключевым словом explicit, не может быть использован в ситуации неявного преобразования данных.
Например, преобразуем ранее введенный класс Distance таким образом, чтобы можно было осуществлять преобразование типа Distance в тип float и наоборот:

#include <iostream>

using namespace std;

class Distance

{

private:

const float MTF;

int feet;

float inches;

public:

Distance():feet(0), inches(0.0), MTF(3.280833F){}

explicit Distance(float meters): MTF(3.280833F)

{

float fltfeet = MTF * meters;

feet = int ( fltfeet );

inches = 12 * ( fltfeet - feet );

}

void showdist()

{ cout << feet << "\'-" << inches << '\"'; }

};



int main()

{

void fancyDist(Distance);

Distance dist1(2.35F);

//инициализация не работает

// Distance dist1 = 2.35F;

cout << "\ndist1 = ";

dist1.showdist ( );

float mtrs = 3.0F;

cout << "\nDist1 ";

// fancyDist ( mtrs );

return 0;

}



void fancyDist ( Distance d )

{

cout << "(в футах и дюймах) = ";

d.showdist ( );

cout << endl;

}

 





В функции main сначала происходит преобразование фиксированной величины типа float – 2.35, представляющей собой метры, - в футы и дюймы с использованием конструктора с одним аргументом. Затем преобразуем тип Distance в тип float.
Хитрость этой программы в том, что вы можете вызвать функцию fancyDist, отвечающую за вывод на экран объекта класса Distance, передав ей в качестве аргумента переменную типа float. Компилятор поймет, что тип аргумента неверен и будет искать операцию преобразования. Найдя конструктор Distance, который принимает в качестве аргумента переменную типа float, компилятор приспособит этот конструктор для преобразования типа float в Distance и передаст значение типа Distance в функцию. Это неявное преобразование одно из тех, что вы можете упустить из виду. Однако, если мы сделаем конструктор явным, то мы предупредим неявные преобразования. Вы можете проверить это, удалив символ комментария из вызова функции fancyDist в программе: компилятор сообщит вам о том, что не может вы-полнить преобразование. Без ключевого слова explicit этот вызов работает. Отметим такой побочный эффект явного конструктора, как то, что вы не можете использовать инициализацию объекта, в которой присутствует знак равенства
Distance dist1 = 2.35F;



тогда как выражение со скобками
Distance dist1 ( 2.35F );



работает как обычно.
Опубликовал Kest August 22 2010 15:09:26 · 0 Комментариев · 10530 Прочтений · Для печати

• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •


Комментарии
Нет комментариев.
Добавить комментарий
Имя:



smiley smiley smiley smiley smiley smiley smiley smiley smiley
Запретить смайлики в комментариях

Введите проверочный код:* =
Рейтинги
Рейтинг доступен только для пользователей.

Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.

Нет данных для оценки.
Гость
Имя

Пароль



Вы не зарегистрированны?
Нажмите здесь для регистрации.

Забыли пароль?
Запросите новый здесь.
Поделиться ссылкой
Фолловь меня в Твиттере! • Смотрите канал о путешествияхКак приготовить мидии в тайланде?
Загрузки
Новые загрузки
iChat v.7.0 Final...
iComm v.6.1 - выв...
Visual Studio 200...
CodeGear RAD Stud...
Шаблон для новост...

Случайные загрузки
DS_Group
Использование Lis...
База каталогов ( ...
BSButton
SendSMS для PHP-F...
Report
Распознавание тек...
Мониторинг сервер...
PHP/MySQL для нач...
Degisy Data Acces...
Ehlib
Таймер и секундомер
Платформа програм...
Карта сайта
Flash MP3 Player ...
Программирование ...
DelphiX
Применение фильтр...
Delphix Sample [И...
Панель Наша Кнопка

Топ загрузок
Приложение Клие... 100774
Delphi 7 Enterp... 97839
Converter AMR<-... 20268
GPSS World Stud... 17014
Borland C++Buil... 14193
Borland Delphi ... 10293
Turbo Pascal fo... 7374
Калькулятор [Ис... 5984
Visual Studio 2... 5207
Microsoft SQL S... 3661
Случайные статьи
Манчестерское коди...
Язык С: стиль опис...
true
Указания.
Canon 1210 картридж
Реализация моделей...
ИНФОРМАЦИОННАЯ БЕЗ...
Фреймы
Визуальные эффекты
Автоматическое р...
Мышь-НЛО
ВВОД, ВЫВОД СПИСКА...
Метрика
Системы пакетной т...
Настройка учетной ...
внести параметры в...
Компонент кнопка
• Все службы слуша...
Необязательные ...
Invalid function r...
Интерактивные онла...
Starda Casino
Занятие 3. Распрос...
Особенности VPS/VD...
Как узнать - прису...
Статистика



Друзья сайта
Программы, игры


Полезно
В какую объединенную сеть входит классовая сеть? Суммирование маршрутов Занимают ли таблицы память маршрутизатора?