Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

pointer-to-class-object to pointer-to-long

1.9K
12 июня 2006 года
smax13
63 / / 03.08.2004
привет.

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

class CLASS{...};

CLASS oclass_1;
CLASS oclass_2;

long* lpmas[2] = {
(long*) &C1,
(long*) &C2
};
...

CLASS* pclass_1 = lpmas[0];
pclass_1 -> ...;

вопрос можно перефразировать.
является ли указатель на объект класса "простым"
32-битным числом (в 32-платформах) или к нему компилятор
что-нибудь присобачивает (типа как 2 байта перед указателем на область
памяти, выделенной оператором new) и можно ли его подобным образом конвертировать?

спасибо.
3
12 июня 2006 года
Green
4.8K / / 20.01.2000
[QUOTE=smax13]
может ли считаться следующая запись корректной.
[/QUOTE]
С точки зрения компилятора - да, с одним замечанием:
CLASS* pclass_1 = (CLASS*)lpmas[0];

С точки зрения концепции ООП - нет.

[QUOTE=smax13]
вопрос можно перефразировать.
является ли указатель на объект класса "простым"
32-битным числом (в 32-платформах)
[/QUOTE]
Да
И вместо long* здесь вполне может быть void*.

[QUOTE=smax13]
можно ли его подобным образом конвертировать?
[/QUOTE]
Нежелательно, т.к. в данном случае нарушается типовая безопасность.
1.9K
13 июня 2006 года
smax13
63 / / 03.08.2004
т. е. по идее, если я знаю, что делаю (знаю, что за указатель получаю),
подобные преобразования вполне безопасны. я так понял?

что значит "нарушается типовая безопасность"?

и ещё один вопрос. где можно достать инфу под названием типа
"каким образом компилятор переводит текст на С++ в машинные комманды". я, конечено, понимаю, что разные компиляторы делают
это по-разному, но всё-таки хотелось бы разъяснить общие вопросы.
3
13 июня 2006 года
Green
4.8K / / 20.01.2000
[QUOTE=smax13]т. е. по идее, если я знаю, что делаю (знаю, что за указатель получаю),
подобные преобразования вполне безопасны. я так понял?
[/QUOTE]
Нет, подобные преобразования не безопасны даже если ты "знаешь, что делаешь". Подобная практика является плохим стилем программирования, которого следует избегать с самого начала.

[QUOTE=smax13]
что значит "нарушается типовая безопасность"?
[/QUOTE]
Это свойство языков программирования высокого уровня.
Всегда должно быть известно кокого типа объект, причем это обеспечивается самим языком (его конструкциями), а не внешней информацией (комментарием в коде или на бумажке).
При приведении типов, которое ты описываешь, теряется информация о типе, т.е. без внешней информации становится не понятным, на что в действительности указывает твой указатель. В программировании на С++ эта проблема называется "проблема void*", что является нарушением типовой безопасности.
350
13 июня 2006 года
cheburator
589 / / 01.06.2006
[QUOTE=smax13]т. е. по идее, если я знаю, что делаю (знаю, что за указатель получаю),
подобные преобразования вполне безопасны. я так понял?

что значит "нарушается типовая безопасность"?
[/QUOTE]
Это значит, если ты ВДРУГ запишешь в массив lpmas указатель на что-то другое вместо CLASS, получишь полную хрень. А компилятор даже не пикнет. Под безопасностью в данном случае подразумевается то, что компилятор может выявить случайно допущенные программистом ошибки.
[QUOTE=smax13]
и ещё один вопрос. где можно достать инфу под названием типа
"каким образом компилятор переводит текст на С++ в машинные комманды". я, конечено, понимаю, что разные компиляторы делают
это по-разному, но всё-таки хотелось бы разъяснить общие вопросы.[/QUOTE]
Не знаю, где ты сможешь достать подобную инфу, лучше спрашивай здесь, что конкретно тебя интересует.
1. Указатели в 32-битных Windows-системах действительно 32-битные и представляют собой просто смещение от 0-го адреса.
2. В 16-битных системах (Windows 3.11, DOS) указатели были 2 видов - дальние (с ключевым словом far) 32-битные (сегмент + смещение, возможность адресации в пределах [0..0x10FFEF]) и ближние 16-битные (с ключевым словом near) (адресация в пределах 64 Кб, т. е. в пределах текущего сегмента).
3. На С/С++ - передача параметра по ссылке и по указателю на уровне машинных кодов не отличаются. Передача ссылки - фактически тоже передача указателя.
4. Ну и естественно указатели на разные типы никак между собой не отличаются на уровне машинных кодов. НО ОСТОРОЖНЕЕ с преобразованиями указателей на объекты производных классов. Там компилятор может изменить само значение указателя; такое, например, может происходить при множественном наследовании.
15K
14 июня 2006 года
foo
33 / / 03.06.2006
так лучше не делать. Это действительно случайность, при наличии виртуальных функций, компилятор запросто может поместить указатель на vtable до того места куда указывает указатель. То есть это может работать с одним компилятором, но при этом не работать с другим.
Если очень хочеться, то пиши в C. C даст тебе полный контроль за всеми указателями. И, кроме того, насколько я помню спецификации, ANSI C++ скажет тебе "error: ..."
3
14 июня 2006 года
Green
4.8K / / 20.01.2000
[QUOTE=foo]так лучше не делать. Это действительно случайность,
[/QUOTE]
Ты не прав. Это не случайность, а закономерность.

[QUOTE=foo]
при наличии виртуальных функций, компилятор запросто может поместить указатель на vtable до того места куда указывает указатель. То есть это может работать с одним компилятором, но при этом не работать с другим.
[/QUOTE]
То же не верно. Это будет работать с любым компилятором.

[QUOTE=foo]
Если очень хочеться, то пиши в C. C даст тебе полный контроль за всеми указателями.
[/QUOTE]
Да и С++ дает "полный контроль за всеми указателями".

[QUOTE=foo]
И, кроме того, насколько я помню спецификации, ANSI C++ скажет тебе "error: ..."[/QUOTE]
Спецификации или стандарт?
Конкретный пункт, плз.
15K
14 июня 2006 года
foo
33 / / 03.06.2006
[QUOTE=Green]Ты не прав. Это не случайность, а закономерность.

То же не верно. Это будет работать с любым компилятором.

Да и С++ дает "полный контроль за всеми указателями".
[/QUOTE]

да? возможно в данной ситуации ты прав. Но если хочешь, я найду пример, когда такого рода преобразование приводит к SEGFAULT ("программа выполнила некорректную операцию..." в терминологии виндовс). Правда, там имеет место быть наследование.
Пример, который продемонстрирует, что нету полного контроля над указателями в C++.

[QUOTE=Green]Спецификации или стандарт?
Конкретный пункт, плз.[/QUOTE]
вот тут ты прав. память меня подвела... Уж и не помню, что там к чему я приводил, что без reinterpret_cast у нифига не вышло, но в данном случае действительно всё работает. И работает согласно стандарту.
3
15 июня 2006 года
Green
4.8K / / 20.01.2000
[QUOTE=foo]да? возможно в данной ситуации ты прав. Но если хочешь, я найду пример, когда такого рода преобразование приводит к SEGFAULT ("программа выполнила некорректную операцию..." в терминологии виндовс). Правда, там имеет место быть наследование.
Пример, который продемонстрирует, что нету полного контроля над указателями в C++.
[/QUOTE]
Чтож интересно было бы посмотреть.
Только сдается мне, что ты путаешь преобразования type1* -> void* -> type1* и type1* -> void* -> type2*, где type2 может быть в наследственной связи с type1.
Мы же говорим ТОЛЬКО про первый вариант (type1* -> void* -> type1*).
585
15 июня 2006 года
honeybeer
297 / / 06.09.2004
перегрузить операторы long* для класса, да и точка =)
3
15 июня 2006 года
Green
4.8K / / 20.01.2000
И что это даст?
Или просто для прикола?
585
15 июня 2006 года
honeybeer
297 / / 06.09.2004
н-и-ч-е-г-о
1.9K
16 июня 2006 года
smax13
63 / / 03.08.2004
ребята, подскажите лучше.
если в локальной области видимости определены

{
char szstr[] = "aaaaa";
char* szstr = "aaaaa";
}

различаются ли они по времени жизни?
есть ли аналогия между второй строкой и, например,
CLASS* pclass = new CLASS;
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог