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

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

Страниц: 1 2 [3] 4   Вниз
  Печать  
Автор Тема: Объясните понятно, доступно и просто как для чайника про приведение типов.  (Прочитано 27493 раз)
mutineer
Гость
« Ответ #30 : Март 11, 2012, 14:38 »

B к C привести динамиком не получится - это разные классы, и они не наследуются один от другого

Я предполагаю, что надо сначала назад от B к А, а потом от А к С верно?

и все равно будет хрень - у тебя объект класса В. Значит легально указывать на него могут указатели типа A* и B*. C* не может легально указывать на объект класса В
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


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


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

Вообще, не стоит юзать касты. Нужно грамотно писать базовые классы.
Записан

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

B к C привести динамиком не получится - это разные классы, и они не наследуются один от другого

Я предполагаю, что надо сначала назад от B к А, а потом от А к С верно?

и все равно будет хрень - у тебя объект класса В. Значит легально указывать на него могут указатели типа A* и B*. C* не может легально указывать на объект класса В

Ясно, значит нельзя...

а вот при такой иерархии:
Код
C++ (Qt)
class A{
public:
   int e;
   virtual void func();
};
void A::func()
{
   e=3;
}
 
class B: public A
{
public:
   double h;
};
 
class C: public B
{
public:
   int c;
};
 

можно от С к А? от А к С?
Записан
lolbla2
Гость
« Ответ #33 : Март 11, 2012, 14:44 »

Вообще, не стоит юзать касты. Нужно грамотно писать базовые классы.

Ну это просто мне интересны возможности этих кастов Улыбающийся Понятно, что в редких случаях это может мне понадобится на практике...
Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


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

как теперь привести от B к С?
Никак, они неприводимы и dynamic_cast совершенно правильно возвращает вам нулевой указатель, так как vB не является указателем на С или его наследник.
Вы можете, конечно, вызвать C* vC = reinterpret_cast<C*> (vB); и получить указатель, но дальше вам уже никто ничего не гарантирует.
Записан
mutineer
Гость
« Ответ #35 : Март 11, 2012, 14:47 »

а вот при такой иерархии:
Код
C++ (Qt)
class A{
public:
   int e;
   virtual void func();
};
void A::func()
{
   e=3;
}
 
class B: public A
{
public:
   double h;
};
 
class C: public B
{
public:
   int c;
};
 

можно от С к А? от А к С?

мы же говорим про dynamic_cast, верно?
C->A можно кастовать всегда, для этого даже необязательно использовать каст, приведение выполнится неявно.
A->C можно кастовать только если объект по указателю является объектом класса С. Если же там объект классов А или В, то каст вернет 0

Общее правило таково - сужать тип можно всегда, а вот расширять только при соблюдении условий
Записан
mutineer
Гость
« Ответ #36 : Март 11, 2012, 14:48 »

Вы можете, конечно, вызвать C* vC = reinterpret_cast<C*> (vB); и получить указатель, но дальше вам уже никто ничего не гарантирует.

Новичкам давать такие советы опасно - они обычно не видят фразу "но дальше вам уже никто ничего не гарантирует." Улыбающийся
Записан
SASA
Гость
« Ответ #37 : Март 11, 2012, 15:09 »

P.S. не подскажешь книгу или статью где описаны всякие такие тонкости?)
http://www.cwer.ru/node/253438/
Купил ещё на первом курсе. Все базовые вещи рассказаны просто и понятно.
Записан
lolbla2
Гость
« Ответ #38 : Март 11, 2012, 15:26 »

Вы можете, конечно, вызвать C* vC = reinterpret_cast<C*> (vB); и получить указатель, но дальше вам уже никто ничего не гарантирует.

Новичкам давать такие советы опасно - они обычно не видят фразу "но дальше вам уже никто ничего не гарантирует." Улыбающийся

Ну я ненастолько новичёк, шишек уже себе понабивал... Читал где-то что reinterpret лучше вообще не использовать, ибо он небезопасен.

Насчёт условий когда приводим от родителя к потомку, то есть расширяем, то вроде родительский класс должен быть полиморфным.
Записан
mutineer
Гость
« Ответ #39 : Март 11, 2012, 15:33 »

Насчёт условий когда приводим от родителя к потомку, то есть расширяем, то вроде родительский класс должен быть полиморфным.

когда приводим указатель от родителя к потомку, то объект по указателю должен быть этим самым потомком. Ну или потомком потомка:)
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

как теперь привести от B к С?
Никак, они неприводимы и dynamic_cast совершенно правильно возвращает вам нулевой указатель, так как vB не является указателем на С или его наследник.
Давайте проверим
Код
C++ (Qt)
#include <QtGui>
 
struct A {
int testA;
 
virtual int Test( void ) { return 0; }
};
 
struct B : public A {
int testB;
 
virtual int Test( void ) { return 1; }
};
 
struct C : public A {
int testC;
 
virtual int Test( void ) { return 2; }
};
 
C * TestCast2C( B * testB )
{
return dynamic_cast <C *> (testB);
}
 
int main(int argc, char **argv)
{
B * testB = (B *) new C();
C * testC = TestCast2C(testB);
printf("testB = %p, testC = %p\n", testB, testC);
return 0;
}
 
Что у Вас печатает?
Записан
mutineer
Гость
« Ответ #41 : Март 11, 2012, 15:51 »

Что у Вас печатает?

Мы тут говорим про кастование через dynamic_cast, а ты читеришь используя C-style cast
Код
C++ (Qt)
B * testB = (B *) new C();

При этом testB указывает на С, но пользоваться таким указателем очень чревато
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

Мы тут говорим про кастование через dynamic_cast, а ты читеришь используя C-style cast
Я тоже о нем говорю
Код
C++ (Qt)
C * TestCast2C( B * testB )
{
return dynamic_cast <C *> (testB);
}
 
Если testB (каким-то образом) был создан как С - dynamic_cast вернет корректный указатель на С. А откуда взялся такой testB - другой вопрос. Др. словами - работает и "вбок" 
Записан
mutineer
Гость
« Ответ #43 : Март 11, 2012, 16:15 »

Мы тут говорим про кастование через dynamic_cast, а ты читеришь используя C-style cast
Я тоже о нем говорю
Код
C++ (Qt)
C * TestCast2C( B * testB )
{
return dynamic_cast <C *> (testB);
}
 
Если testB (каким-то образом) был создан как С - dynamic_cast вернет корректный указатель на С. А откуда взялся такой testB - другой вопрос. Др. словами - работает и "вбок" 

скажем так. работает приведение к корректному типу не важно откуда. а по поводу "вбок" - скастить твой указатель обратно в B* просто динамиком все равно не получится)))
Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


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

Что у Вас печатает?
У меня:
testB = 00676A90, testC = 00000000

Что это доказывает? Что в разных компиляторах UB может давать разный результат. Подмигивающий
Записан
Страниц: 1 2 [3] 4   Вверх
  Печать  
 
Перейти в:  


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