Russian Qt Forum
Ноябрь 23, 2024, 09:56 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3 4   Вниз
  Печать  
Автор Тема: Объясните понятно, доступно и просто как для чайника про приведение типов.  (Прочитано 27476 раз)
lolbla2
Гость
« : Март 06, 2012, 19:33 »

Звачем нужны dynamic_cast, static_cast, reinterpret_cast, qobject_cast и т д?
Сколько статей читал, толком суть не понял чот((
Ведь вроде можно проще приводить к типам. например

Код
C++ (Qt)
int x=9;
float y= (float)x;
 

а между float и double вообще неявное приведение, то есть можно прям вот так:

Код
C++ (Qt)
float x=3.231;
double g=x; //неявно приводится к double
 
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #1 : Март 06, 2012, 19:57 »

Ну вообще-то форум - не для изучения основ, та что придется отправлять на гугл  Улыбающийся Просто наберите напр static_cast C++ попадете на Алену, девушка доходчиво пишет. Обижаться на форумчан не надо, никому не охота переписывать гугл - а ответ на этот вопрос может быть только таким.

По поводу простых типов. Если 2 типа совместимы по присваиванию, то один из них всегда "старше" а др "младше".  Если младший присваивается старшему, никакие приведения не нужны. Примеры

Код
C++ (Qt)
float f = 0.5f;
double d = 2.1;
int i1, i2;
 
f = i1;     // float "старше" int, все норм
f = d;     // а здесь double старше, компилятор может вякнуть варнингом
f = (float) d;  // сказали компилятору что согласны с потерей точности
 
// результат арифметики возвращается как старший тип
i1 = 2;
i2 = 3;
d = (i1 + i2) / 2;   // результат d = 2.0;
d = (i1 + i2) / 2.0;   // результат d = 2.5;
 
Записан
Blackwanderer
Гость
« Ответ #2 : Март 06, 2012, 19:59 »

dynamic_cast - приведение указателей на классы из одной иерархии (указатель на родителя к указателю на потомка и наоборот); проверка на корректность приведение выполняется всегда (в процессе выполнения программы), некорректное приведение не выполняется

static_cast - приведение любых типов (для базовых типов аналогичен привидению в стиле C, для классов и указателей более строго проверяет корректность приведения); проверка на корректность выполняется всегда (на этапе компиляции), некорректное приведение не выполняется только в наиболее очевидных случаях

reinterpret_cast - приведение любых типов; проверка на корректность не выполняется.

Привидение в стиле C, вначале пробует static_cast, затем, если не получилось, reinterpret_cast, т.е. приведение в стиле C потенциально более опасно.
Записан
Blackwanderer
Гость
« Ответ #3 : Март 06, 2012, 20:04 »

Ну вообще-то форум - не для изучения основ
Не согласен, что это - основы. Это, скорее, уже тонкости языка.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #4 : Март 06, 2012, 20:15 »

dynamic_cast - приведение указателей на классы из одной иерархии (указатель на родителя к указателю на потомка и наоборот); проверка на корректность приведение выполняется всегда (в процессе выполнения программы), некорректное приведение не выполняется
Ну если уж вдаваться в тонкости, то dynamic_cast может приводить и не только родителя к потомку
Код
C++ (Qt)
class A {..};
class B : public A {..};
class C : public A {..};
...
B * b = ..
C * c = dynamic_cast <C *> b;
// с - нормальный указатель на объект класса С (если он был таким создан)
 
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #5 : Март 06, 2012, 23:42 »

еще забыли про const_cast - снимает модификатор const с переменной
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
lolbla2
Гость
« Ответ #6 : Март 07, 2012, 09:33 »

еще забыли про const_cast - снимает модификатор const с переменной

не забыл, просто с const_cast всё ясно и понятно, а вот с остальными не так уж.
Записан
lolbla2
Гость
« Ответ #7 : Март 07, 2012, 09:37 »

Ну вообще-то форум - не для изучения основ, та что придется отправлять на гугл  Улыбающийся Просто наберите напр static_cast C++ попадете на Алену, девушка доходчиво пишет. Обижаться на форумчан не надо, никому не охота переписывать гугл - а ответ на этот вопрос может быть только таким.

По поводу простых типов. Если 2 типа совместимы по присваиванию, то один из них всегда "старше" а др "младше".  Если младший присваивается старшему, никакие приведения не нужны. Примеры

Код
C++ (Qt)
float f = 0.5f;
double d = 2.1;
int i1, i2;
 
f = i1;     // float "старше" int, все норм
f = d;     // а здесь double старше, компилятор может вякнуть варнингом
f = (float) d;  // сказали компилятору что согласны с потерей точности
 
// результат арифметики возвращается как старший тип
i1 = 2;
i2 = 3;
d = (i1 + i2) / 2;   // результат d = 2.0;
d = (i1 + i2) / 2.0;   // результат d = 2.5;
 

То есть эти все ..._cast для того чтобы совершать преобразование типов между без потери данных, я так понимаю, верно?

Кстати, а если попоробовать преобразовать  не связанные никак типы, то есть:
Код
C++ (Qt)
class A{....};
class B{...};
 
A * typeA;
B *typeB;
B = dynamic_cast<*B> typeA; // dynamic_cast вернёт NULL?
 
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #8 : Март 07, 2012, 09:37 »

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

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
lolbla2
Гость
« Ответ #9 : Март 07, 2012, 09:41 »

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

аа так это получается все эти .._cast это С++ стиль приведения типов, а тот стиль Сшный ?
Записан
lolbla2
Гость
« Ответ #10 : Март 07, 2012, 09:51 »

dynamic_cast - приведение указателей на классы из одной иерархии (указатель на родителя к указателю на потомка и наоборот); проверка на корректность приведение выполняется всегда (в процессе выполнения программы), некорректное приведение не выполняется

static_cast - приведение любых типов (для базовых типов аналогичен привидению в стиле C, для классов и указателей более строго проверяет корректность приведения); проверка на корректность выполняется всегда (на этапе компиляции), некорректное приведение не выполняется только в наиболее очевидных случаях

reinterpret_cast - приведение любых типов; проверка на корректность не выполняется.

Привидение в стиле C, вначале пробует static_cast, затем, если не получилось, reinterpret_cast, т.е. приведение в стиле C потенциально более опасно.


спасибо, вполне понятно объяснил и без лишних слов))
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #11 : Март 07, 2012, 15:19 »

То есть эти все ..._cast для того чтобы совершать преобразование типов между без потери данных, я так понимаю, верно?
Потеря данных может быть неизбежной, просто _cast показывает это четко, рельефно

Кстати, а если попоробовать преобразовать  не связанные никак типы, то есть:
Код
C++ (Qt)
B = dynamic_cast<*B> typeA; // dynamic_cast вернёт NULL?
 
До этого дело не дойдет, компилятор не пропустит. А вот приведение (B *) в С стиле пройдет - и потом найти концы может быть непросто
Записан
lolbla2
Гость
« Ответ #12 : Март 11, 2012, 12:31 »

Хотелось бы понять ещё некоторые тонкости:

Код
C++ (Qt)
class A{
public:
int e;
}
class B: public A
{
public:
double h;
}
 
.....
// делаем вот тут такое
A* vA = new A;
vA->e=3;
B* vB= dynamic_cast<*B> vA;
// собственно вопрос: какие будут значения полей у vB, т.е. vB.e, vB.h какие будут иметь значения?
// то есть при преобразовании типо их поля как друг другу передаются?
 
...
 
 

а наоборот если, то тогда что?

Код
C++ (Qt)
B* vB = new B;
vB.h= 2.345;
vB.e=1;
A *vA = dynamic_cast<*A> vB;
// каким будет значение в vA.e ?
 
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #13 : Март 11, 2012, 12:42 »

vB.e будет 3.
vB.h не определено.
Наоборот, h потеряется, произойдет "срезка". e останется 1.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #14 : Март 11, 2012, 12:43 »

Код
C++ (Qt)
.....
// делаем вот тут такое
A* vA = new A;
vA->e=3;
B* vB= dynamic_cast<*B> vA;
// собственно вопрос: какие будут значения полей у vB, т.е. vB.e, vB.h какие будут иметь значения?
// то есть при преобразовании типо их поля как друг другу передаются?
 
...
 
 
Не происходит никакой "передачи/копирования". dynamic_cast разберется что vA был создан как "А" (а не как "B") и вернет NULL

Код
C++ (Qt)
а наоборот если, то тогда что?
 
B* vB = new B;
vB.h= 2.345;
vB.e=1;
A *vA = dynamic_cast<*A> vB;
// каким будет значение в vA.e ?
 
Здесь никакое приведение не нужно т.к. известно что B порожден от A. Значение "e" будет тем же что установили, и адреса vA и vB будут равны

А книжки все-таки надо читать (ну иногда  Улыбающийся)
« Последнее редактирование: Март 11, 2012, 12:45 от Igors » Записан
Страниц: [1] 2 3 4   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.232 секунд. Запросов: 23.