Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Кастинг вверх / 25 сообщений из 43, страница 1 из 2
13.12.2012, 13:26
    #38077557
Lumix
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кастинг вверх
Внутри двух моих соседних тем 13615394 про автодроп и 13615394 про неявность образовалась одна лемма, которую я решил вынести в отдельный пост, потому что там и так уже замес по полной программе)))

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
#include <iostream>
using namespace std;

class A { public: int a; A() { a = 5; }} ;
class B : public A { public: int b, c; B() : A() { b = 6, c = 7; }}; 

int main()
{
    B* b = (B*) new A;
    cout << b->a << endl; // 5
    cout << b->b << endl; // 0 ))) 
    cout << b->c << endl; // 131074 )))
    return 0;
}



Короче, есть желание разобраться что происходит, когда мы сишно ака грязно кастим родителя в дочку. Возникает два вопроса:

1. грязь свеху (b=0, c=131074) это просто грязь из свободной памяти и и тогда все ок, или это кусок от какого-то реального объекта и мы кому-то реально что-то поломали в своей же программе??

2. если это просто грязь, то какой самый простой способ тупо занулить этот оверхед??

3. какие существуют самые простые, безболезненные, экономичные и безопасные методы неявного кастинга вверх, когда кастируемый объект занимает меньший объем, чем кастоприемник??
...
Рейтинг: 0 / 0
13.12.2012, 13:41
    #38077600
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кастинг вверх
Lumix, ты меня просто поражаешь своей скоростью продуцирования бредовых идей.
Самое интересное как тебя самого не корчит от противоречий и нарушений базовых
правил?

Ну что это такое за мерзость ты написал? Что это за даункастинг в первой строке?
...
Рейтинг: 0 / 0
13.12.2012, 13:52
    #38077621
sherzod_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кастинг вверх
mayton,

Думаю, возможно два варианта, первое, или это человек с идиосинкразией к обучению, или что это тролль, не осознавший еще что он тролль. В любом случае предлагаю не обсуждать подобный код, по вполне практичным соображениям: поиск по форуму пополнится очередной ахинеей, снизится добротность форума, и судя по предыдущим топикам, человек не в состоянии понять что ему советуют.
...
Рейтинг: 0 / 0
13.12.2012, 14:00
    #38077641
m_Sla
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кастинг вверх
Lumix, твой код примерно соответствует:
Код: plaintext
1.
2.
3.
4.
5.
    int *a= new int[1];
    a[0]=5;
    cout << a[0] << endl;
    cout << a[1] << endl;
    cout << a[2] << endl;
...
Рейтинг: 0 / 0
13.12.2012, 14:39
    #38077774
Lumix
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кастинг вверх
maytonНу что это такое за мерзость ты написал?

Это наезд? )))

maytonЧто это за даункастинг в первой строке?

Я бы скорее назвал это апкастингом, если уж на то пошло. Даункастинг это так:
Код: plaintext
1.
A* a = (A*) new B;
...
Рейтинг: 0 / 0
13.12.2012, 14:39
    #38077778
Lumix
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кастинг вверх
sherzod_,

чё обиделись на меня что-ли?...
...
Рейтинг: 0 / 0
13.12.2012, 14:40
    #38077781
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кастинг вверх
LumixКороче, есть желание разобраться что происходит, когда мы сишно ака грязно кастим родителя в дочку. Возникает два вопроса:


Происходит UB (undefined behavior), т.е. поведение программы непредсказуемо.
Если реального обращения с b как с B не будет, скорее всего, ничего не будет.
Если попытаются реально к b обратиться как к B, а не A, скорее всего, будет защита памяти и крах программы.

Lumix1. грязь свеху (b=0, c=131074) это просто грязь из свободной памяти и и тогда все ок, или это кусок от какого-то реального объекта и мы кому-то реально что-то поломали в своей же программе??


Это может быть всё что угодно, чаще всего, это либо какой-то мусор (слючайно заполненные данные) или защита памяти, если OS эту память защищает. Но это не вопрос С++, это вопрос реализации, как там сделано, и какой объект (тут он динамический, но такое может быть с объектом любого класса памяти).

Lumix2. если это просто грязь, то какой самый простой способ тупо занулить этот оверхед??

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


0) это не просто грязь, это вообще не грязь, это UB -- т.е. твоя программа попросту невалидна. Как она при этом будет работать -- неизвестно.

1) это не кастинг вверх, это кастинг вниз. Он так и называется -- downcast, в безопасном варианте -- type-safe downcast.
Кастинг вверх всегда безопасен. Кастинг вниз требует проверки реального типа объекта.

2) единственный и он же безопасный метод выполнения downcast -- делать его всегда type-safe downcast. В С++ это dynamic_cast или его проприетарные аналоги из разных библиотек, которые реализуют по сути тот же dynamic_cast своими методами.
...
Рейтинг: 0 / 0
13.12.2012, 14:41
    #38077783
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кастинг вверх
sherzod_mayton,

Думаю, возможно два варианта, первое, или это человек с идиосинкразией к обучению, или что это тролль, не осознавший еще что он тролль. В любом случае предлагаю не обсуждать подобный код, по вполне практичным соображениям: поиск по форуму пополнится очередной ахинеей, снизится добротность форума, и судя по предыдущим топикам, человек не в состоянии понять что ему советуют.

Давайте без наездов.

Явно видно, человек учится, только ему просто не у кого учиться.
...
Рейтинг: 0 / 0
13.12.2012, 14:42
    #38077786
Lumix
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кастинг вверх
m_SlaLumix, твой код примерно соответствует:
Код: plaintext
1.
2.
3.
4.
5.
    int *a= new int[1];
    a[0]=5;
    cout << a[0] << endl;
    cout << a[1] << endl;
    cout << a[2] << endl;



Ок, понял.

А в этом случае a[1] и a[2] чью-то конкретную память берут (какого-то живого объекта) или свободную, ничейную?? Это просто неэтичная операция или кастиг вверх может уронить программу??
...
Рейтинг: 0 / 0
13.12.2012, 14:49
    #38077819
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кастинг вверх
Это по уровню идиотизма аналог кода был. Да, согласен.

Lumix
Ок, понял.

А в этом случае a[1] и a[2] чью-то конкретную память берут (какого-то живого объекта) или свободную, ничейную??


Язык С++ это не специфицирует. Как это реализовано -- зависит от конкретного компилятора, его моделей памяти и способов её организации. Они могут взять чужую память, другого объекта, могут взять свободную память, могут вообще вызвать ошибку по защите памяти, особенно вероятно, если значения индексов будут большими или отрицательными.

LumixЭто просто неэтичная операция или кастиг вверх может уронить программу??


Может уронить, и очень легко в современных системах.
Если объект динамически созданный, как в твоём примере, то это почти 100% крах программы в современных операционках и компиляторах.
...
Рейтинг: 0 / 0
13.12.2012, 14:51
    #38077826
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кастинг вверх
1)LumixЯ бы скорее назвал это апкастингом, если уж на то пошло. Даункастинг это так:
Код: plaintext
1.
A* a = (A*) new B;


Нет.

2)
Следующее выражение перепиши с использованием dynamic_cast.

Код: plaintext
1.
B* b = (B*) new A;



И расскажи что случилось в runtime.
...
Рейтинг: 0 / 0
13.12.2012, 15:03
    #38077857
Lumix
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кастинг вверх
MasterZivЕсли реального обращения с b как с B не будет, скорее всего, ничего не будет.

ок, понятно

MasterZivЕсли попытаются реально к b обратиться как к B, а не A, скорее всего, будет защита памяти и крах программы.

ок, понятно


MasterZiv0) это не просто грязь, это вообще не грязь, это UB -- т.е. твоя программа попросту невалидна. Как она при этом будет работать -- неизвестно.

понятно...
тогда и затирание оверхеда нулями тоже бессмсленный шаг...

блин, тогда получается любой кастинг вниз чтобы защититься от UB вынуждает нас создавать новый объект, в который мы кастим, копировать кастируемый объект и потом затирать старый, если он не нужен


MasterZiv1) это не кастинг вверх, это кастинг вниз. Он так и называется -- downcast, в безопасном варианте -- type-safe downcast.
Кастинг вверх всегда безопасен. Кастинг вниз требует проверки реального типа объекта.

2) единственный и он же безопасный метод выполнения downcast -- делать его всегда type-safe downcast. В С++ это dynamic_cast

ок, с направлением разобрался
спасибо за ключевое слово type-safe downcast

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

MasterZivили его проприетарные аналоги из разных библиотек, которые реализуют по сути тот же dynamic_cast своими методами.

а динамик под капотом это всегда копирование или он как-то по-хитрому оверхед пришивает ну типа как кусочки файлов на поверхности диска разбросаны, а операционная система имплиситно потом собирает в один??
...
Рейтинг: 0 / 0
13.12.2012, 15:05
    #38077862
Lumix
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кастинг вверх
mayton1)LumixЯ бы скорее назвал это апкастингом, если уж на то пошло. Даункастинг это так:
Код: plaintext
1.
A* a = (A*) new B;


Нет.


да, мне уже объяснили, что направление приращивания идет вниз, то родитель это всегда топ.
из-за "мерзость" я подумал даункастинг в смысле "ты чё даун что ли?"
...
Рейтинг: 0 / 0
13.12.2012, 15:07
    #38077872
Lumix
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кастинг вверх
MasterZivLumixА в этом случае a[1] и a[2] чью-то конкретную память берут (какого-то живого объекта) или свободную, ничейную??


Язык С++ это не специфицирует. Как это реализовано -- зависит от конкретного компилятора, его моделей памяти и способов её организации. Они могут взять чужую память, другого объекта, могут взять свободную память, могут вообще вызвать ошибку по защите памяти, особенно вероятно, если значения индексов будут большими или отрицательными.


Ок, понятно

MasterZivLumixЭто просто неэтичная операция или кастиг вверх может уронить программу??


Может уронить, и очень легко в современных системах.
Если объект динамически созданный, как в твоём примере, то это почти 100% крах программы в современных операционках и компиляторах.

Ок, понятно
...
Рейтинг: 0 / 0
13.12.2012, 15:09
    #38077875
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кастинг вверх
Lumix, ну вот погугли по RTTI, downcasting, dynamic_cast..

Не обижайся! Но со стороны звучит так. " - Ребят я тут с утра поел немного говна навоза. И у меня болит живот.
Откуда у меня в животе интоксикация? "...

Сам ведь себе Злобный Буратино.
...
Рейтинг: 0 / 0
13.12.2012, 15:14
    #38077889
Lumix
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кастинг вверх
mayton
2)
Следующее выражение перепиши с использованием dynamic_cast.

Код: plaintext
1.
B* b = (B*) new A;



И расскажи что случилось в runtime.

Я конечно сейчас попробую, но меня пока пугает, что динамик требует виртуалок в базе, а у нас доступа к базе нет, мы от базы просто наследуемся и соотв. динамик к ней применять может не получиться...
Код: plaintext
1.
2.
3.
4.
A* get A(); // внешняя либа, не наша
class B : public A { };
shared_ptr<b>& b() { .... }
b() = dynamic_cast<B>(getA()); // требует виртуалок А...



Про как спрятать это хозяйство под капот я тему не трогаю, потому что эта тема конкретно про даункастинг
...
Рейтинг: 0 / 0
13.12.2012, 15:19
    #38077908
Lumix
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кастинг вверх
maytonНе обижайся!

я и не обижаюсь. Я лишь выяснял вопрос насчет наездов и обид с одной целью: можно ли мне продолжать поиск или уйти из темы, чтобы не нервировать людей, ведь там были предложения "а давайте тему игнорить!!"

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

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

с тем же даункастингом
я ведь реально подумал, что это такой наезд, что типа я даун, а оказалось что это реальный термин такой!! )))

я помню фильм был какой-то старый с Вуппи Голберг. она там тренировала баскетбольную команду и назвала чувака негра, который был в защите, назвала его black hole, он подумал что это расистский наезд, а оказалось, что она имела ввиду черную дыру, которая в космосе, в которой все исчезает...
...
Рейтинг: 0 / 0
13.12.2012, 15:22
    #38077917
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кастинг вверх
Lumixя ведь реально подумал, что это такой наезд, что типа я даун, а оказалось что это реальный термин такой!! )))
...
Рейтинг: 0 / 0
13.12.2012, 15:36
    #38077950
sherzod_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кастинг вверх
Lumix,

уважаемый Lumix, все делается для того чтобы обратить ваше внимание на те вещи на которых вам следует сконцентрироваться. В том числе на изучении базовых элементов, принципов, конструкций языка. А "наезды" (здесь и в соседних топиках), это своего рода порки, которые вы заслужили. Кстати обижаться на вас никто не собирается, этого как раз вы еще не заслужили.

Прежде чем спорить и отвечать на советы, попытайтесь как минимум понять, осмыслить что вам пишут, и тем более то что пишите вы. И все будет тип-топ. Обещаю.

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

ЗЫ с обиняками. Не употребляйте столько непонятных терминов. Вы заставляете наши эго корчиться от осознания собственной ничтожности.
...
Рейтинг: 0 / 0
13.12.2012, 15:38
    #38077955
egorych
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кастинг вверх
Lumixа динамик под капотом это всегда копирование или он как-то по-хитрому оверхед пришивает ну типа как кусочки файлов на поверхности диска разбросаны, а операционная система имплиситно потом собирает в один??нет, динамик каст это всегда проверка на допустимость, если приведение невозможно, то динамик каст вернёт 0. смотри:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
class A { virtual ~A() {} };
class B : public A { virtual ~B() {} };

A *a = new A;
A *b = new B;
B *c = dynamic_cast< B*>( a );  // здесь c == 0, потому что (*a) не является объектом класса B
B *d = dynamic_cast< B*>( b );  // здесь d == b, потому что (*b) - является объектом класса B

и, для того, чтобы воспользоваться возможностями dynamic_cast, тебе необходимо иметь в классе хотя бы одну виртуальную функцию

Но на самом деле, тебе не нужен такой кривой каст. Всё, что тебе нужно - это сделать твой globalStorage указателем на базовый класс ( class A, в твоих примерах ) и функцию b() сделать возвращающей тип A*, и тогда ты 100% гарантируешь, что с любым объектом, который она вернёт, работа возможна только в рамках интерфейса базового класса.

Возвращаясь к посылу именно этого треда, то, если малька перезаточить твой исходный пример, то падения можно добиться прямо не отходя от кассы:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
#include <iostream>
using namespace std;

class A { public: int a; A() { a = 5; }} ;
struct B : public A 
{ 
	int *b, *c; 
	B() : A(), b( new int( 6 ) ), c( new int( 7 ) ) {} 
	virtual ~B() { delete b; delete c; }
}; 

int main()
{
 	B* b = (B*) new A;
	cout << &b->a << " " << b->a << endl; 
	cout << &b->b << " " << b->b << " " /*<< *b->b*/ << endl;  // закомментированный кусок приводит к падению
	cout << &b->c << " " << b->c << " " /*<< *b->c*/ << endl;  // или не приводит, что ещё хуже
	return 0;
}
...
Рейтинг: 0 / 0
13.12.2012, 15:46
    #38077976
egorych
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кастинг вверх
sherzod_, ну ладно уж, воспитатель прям. Человек ведь задаёт вопросы, и постепенно, приходит к пониманию.
...
Рейтинг: 0 / 0
13.12.2012, 15:49
    #38077988
egorych
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кастинг вверх
Lumixно меня пока пугает, что динамик требует виртуалок в базе, а у нас доступа к базе нет, мы от базы просто наследуемся и соотв. динамик к ней применять может не получиться...вообще говоря, если в базе нет виртуального деструктора, то наследоваться от такого класса категорически не рекомендуется, потому что вероятность утечки памяти практически 100%.
Если это действительно так, то следует вместо наследования использовать агрегацию.
...
Рейтинг: 0 / 0
13.12.2012, 15:54
    #38078006
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кастинг вверх
У меня уже в голове созрела книга под названием "Вы можете сделать это в С++, но этого делать нельзя."
...
Рейтинг: 0 / 0
13.12.2012, 16:00
    #38078035
Lumix
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кастинг вверх
maytonУ меня уже в голове созрела книга под названием "Вы можете сделать это в С++, но этого делать нельзя."

где можно оставить предзаказ? ;)
...
Рейтинг: 0 / 0
13.12.2012, 16:04
    #38078047
Lumix
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кастинг вверх
egorychLumixно меня пока пугает, что динамик требует виртуалок в базе, а у нас доступа к базе нет, мы от базы просто наследуемся и соотв. динамик к ней применять может не получиться...вообще говоря, если в базе нет виртуального деструктора, то наследоваться от такого класса категорически не рекомендуется, потому что вероятность утечки памяти практически 100%.
Если это действительно так, то следует вместо наследования использовать агрегацию.

Вот это да!! Охренеть!!
А это правило распространяется на наследников третьего и глубже уровней??

Код: plaintext
1.
2.
3.
4.
5.
6.
class U {};
class D : public U {}; // опасно!!

class A { public: virtual ~A(){};};
class B : public A { public: ~B(){}; }; // безопасно
class C : public B {}; // опасно или безопасно??
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Кастинг вверх / 25 сообщений из 43, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]