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

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

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

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

Кажется ты меня чуток обманул, родителя к потому нельзя приводить, только наоборот потомка можно к родителю привести. Щас попробовал, при приведении таком:
Код
C++ (Qt)
class A{
public:
   int e;
   virtual void func();
};
void A::func()
{
   e=3;
}
 
class B: public A
{
public:
   double h;
};
 
int main(int argc, char *argv[])
{
   QCoreApplication a(argc, argv);
 
   B* vB = new B;
   vB->h= 2.345;
   vB->e=14;
   A *vA = dynamic_cast<A*> (vB);
   qDebug() << vA->e;
   return a.exec();
} //Всё ок vA->e=14;
 

Но при таком преобразовании:
Код
C++ (Qt)
   A* vA = new A;
   vA->e = 34;
   B* vB = dynamic_cast<B*> (vA); //dynamic_cast вернул NULL
   qDebug() << vB;
 

Что говорит о том, что нельзя папу преобразовать к сыну  Смеющийся
« Последнее редактирование: Март 11, 2012, 13:05 от lolbla2 » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

...
Что говорит о том, что нельзя папу преобразовать к сыну  Смеющийся
Он ведь dynamic  Улыбающийся

Код
C++ (Qt)
   A * vA = new A();
   B* vB = dynamic_cast<B*> (vA); //dynamic_cast вернул NULL
 
   vA = new B();
   vB = dynamic_cast<B*> (vA); //  а теперь уже не NULL
 
Записан
lolbla2
Гость
« Ответ #17 : Март 11, 2012, 13:28 »

...
Что говорит о том, что нельзя папу преобразовать к сыну  Смеющийся
Он ведь dynamic  Улыбающийся

Код
C++ (Qt)
   A * vA = new A();
   B* vB = dynamic_cast<B*> (vA); //dynamic_cast вернул NULL
 
   vA = new B();
   vB = dynamic_cast<B*> (vA); //  а теперь уже не NULL
 

ммм.... как здорово, оказывается надо знать такие чёткие тонкости. Значит получается, при преобразовании от родителя к потомку все поля, которых у родителя нет после преобразования будут иметь "мусор" ? То есть

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

P.S. не подскажешь книгу или статью где описаны всякие такие тонкости?)
Записан
mutineer
Гость
« Ответ #18 : Март 11, 2012, 13:32 »

ммм.... как здорово, оказывается надо знать такие чёткие тонкости. Значит получается, при преобразовании от родителя к потомку все поля, которых у родителя нет после преобразования будут иметь "мусор" ? То есть

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

P.S. не подскажешь книгу или статью где описаны всякие такие тонкости?)

не будет там никакого мусора - при new B() конструктор класса B инициализировал (если в нем прописана эта инициализация, конечно) все поля объекта класса В
Записан
qt_user
Гость
« Ответ #19 : Март 11, 2012, 13:43 »

ммм.... как здорово, оказывается надо знать такие чёткие тонкости. Значит получается, при преобразовании от родителя к потомку все поля, которых у родителя нет после преобразования будут иметь "мусор" ? То есть

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

P.S. не подскажешь книгу или статью где описаны всякие такие тонкости?)

vA это всего лишь указатель на объект класса В и не больше, тонкость состоит только
в том что класс А ничего не знает о "новых" полях класса В и указатель на класс А собственно
тоже в таком случае чтобы получить доступ к полю h надо сделать приведение:
Код:
vA = new B();
(vB *)vA->h;

p.s: доходчиво написано у Шилдта и конечно же документация:
http://www.cplusplus.com/doc/tutorial/typecasting/ там все разжевано
« Последнее редактирование: Март 11, 2012, 13:45 от qt_user » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

Значит получается, при преобразовании от родителя к потомку все поля, которых у родителя нет после преобразования будут иметь "мусор" ? То есть

Код
C++ (Qt)
vA = new B();
vB = dynamic_cast<B*> (vA); // у класса B есть поля которых нет у А, значит в  vB.h находится мусор, и также было бы с другими полями если бы они были да?
 
Знову за рибу грошi  Плачущий  dynamic_cast делает из одного указателя другой, который может совпадать с исходным или нет. Содержимое/размеры объектов он никак не трогает, они остаются как были созданы. "Мусор" (и обращение к полям которых нет) - это проблема приведения в стиле С,  dynamic_cast как раз и был придуман чтобы этого избежать.

P.S. не подскажешь книгу или статью где описаны всякие такие тонкости?)
Здесь много людей гораздо более начитанных чем я, у них и спрашивайте
Записан
lolbla2
Гость
« Ответ #21 : Март 11, 2012, 13:47 »

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

Ну просто спрашиваю у тех, кто в теме отвечает.
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


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


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

lolbla2, почитай Александреску, Саттера и Майерса.
Записан

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

lolbla2, почитай Александреску, Саттера и Майерса.

а то я тут за Страуструпа взялся, про приведение типов чот там недостаточно подробно
Записан
mutineer
Гость
« Ответ #24 : Март 11, 2012, 13:54 »

lolbla2, почитай Александреску, Саттера и Майерса.

а то я тут за Страуструпа взялся, про приведение типов чот там недостаточно подробно

Страуструп лишним тоже не будет
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


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


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

Страуструп будет сложноват, лучше начинать с чего-нибудь по-проще.
Записан

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

Страуструп будет сложноват, лучше начинать с чего-нибудь по-проще.

Да норм, я же не совсем уж новичёк... 3-4 года программирую, но не особо активно конечно
Записан
lolbla2
Гость
« Ответ #27 : Март 11, 2012, 14:27 »

чуток изменил иерархию классов
Код
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 A
{
public:
   int c;
};
 

как теперь привести от B к С?

Код
C++ (Qt)
A* vA = new B;
   vA->e = 34;
   B* vB = dynamic_cast<B*> (vA);
   qDebug() << vB->e<<" "<< vB->h<<endl;
 
 
   C* vC = dynamic_cast<C*> (vB); // так NULL  :(
   qDebug() << vC;
 
Записан
mutineer
Гость
« Ответ #28 : Март 11, 2012, 14:32 »

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

Динамик кастует либо вверх по иерархии, либо вниз. А это, грубо говоря, вбок))
Записан
lolbla2
Гость
« Ответ #29 : Март 11, 2012, 14:33 »

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

Я предполагаю, что надо сначала назад от B к А, а потом от А к С верно?
Записан
Страниц: 1 [2] 3 4   Вверх
  Печать  
 
Перейти в:  


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