![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| Master01 |
|
||||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 89 Регистрация: 22.8.2007 Репутация: 2 Всего: 2 |
всем, привет
вот решил заняться smart pointer-ами. Нашёл замечательную книжку (хочется так думать) Джеффа Элджера и углубился в эту увлекательную область написал вот что
и
CInteger - просто некоторый класс. CPInteger - умный указатель для него. в Main пишу следуещее: CPInteger psp; psp->msgbox(); в результате чего на экране появляется соответствующий messadgebox, т.е. всё работает нормально. Далее изменяю CPInteger(см. 11 строку)
т.е. теперь перегруженный оператор -> всегда возвращает NULL, запускаю на выполнение... ВСЁ РАБОТАЕТ!!!!! ради смеха пробовал return reinterpret_cast<CInteger>(87878787) и что вы думаете? во время отладки стрелочка дебаггера благополучно перескакивает на строчку "void __stdcall msgbox() { MessageBox(NULL,"CInteger.msgbox","CInteger.msgbox",MB_OK); }" , в в окошке watches значение указателя this отображается как 53CEC83!!! т.е. там есть объект... я конечно понимаю что это smart поинтеры.. но всё ж Сильно подозреваю компилятор. использую Visual studio 2003, я в принципе на неё только пересел, может что-то не так настроил..... Заранее спасибо. |
||||||
|
|||||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
||||
|
||||
| Master01 |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 89 Регистрация: 22.8.2007 Репутация: 2 Всего: 2 |
О! наконец-то, вылетело!!
появилось сообщение следующего содержания - "Access Violation Writing location 0x00000004". но у меня есть 2 вопроса: 1. неужели вызов функции по адресу 0x00000000 возможен??? вроде бы само по себе действие подобного рода должно вызывать остановку программы. 2. допустим что мы всё же прыгнули на 0 адресс, но не может же быть такого чтоб там где-то в памяти случайно оказалось то что нам нужно - message box всё же появлялся и причём с правильным текстом (специально менял, чтоб убедиться). Значит всё же что-то в памяти весело.. хотя никакой объект не создавался. Откуда там это взялось? |
|||
|
||||
| mes |
|
||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
Эти вопросы возникли из за неправильного представления работы метода. Метод эта такая же функция , которой неявно передается дополнительный параметр this т.е.
вызов с нулевым обэектом такой функции никакого вреда не принесет, так как параметр this не используется однако доработанный метод
как видите при таком варианте, значение this используется. Поэтому теперь при вызове метода с невалидным указателем , запись значения по чужому адресу спровоцирует Access Violation Добавлено @ 21:45 да забыл сказать, что metod и eго содержимое хранится не в объекте, а статически. А описание методов внутри класса нужно не для того , чтоб создались методы, а для чтоб ограничить права доступа к методам и для удобного наследования этих правил. Это сообщение отредактировал(а) mes - 21.9.2008, 21:46 |
||||
|
|||||
| J0ker |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: 4 Всего: 14 |
сорри за оффтопик, но зачем вам __stdcall?
Добавлено через 4 минуты и 6 секунд если только эта функция не virtual... |
|||
|
||||
| Master01 |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 89 Регистрация: 22.8.2007 Репутация: 2 Всего: 2 |
mes, спасибо за толковое объяснение, теперь всё ясно.
JOker, в данном примере использование __stdcall скорее привычка нежели необходимость. всем спасибо. вопрос закрыт. |
|||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
А зачем нужна эта привычка, если не секрет? |
|||
|
||||
| Master01 |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 89 Регистрация: 22.8.2007 Репутация: 2 Всего: 2 |
мне просто с COM приходилось иметь дело, а там все вызовы обязательно __stdcall, чтобы избежать проблем при написание клиента и компонента с использованием разных языков и компиляторов а вы находите что-то негативное в этом формате вызова?или просто за чистоту кода? |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
||||
|
||||
| Master01 |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 89 Регистрация: 22.8.2007 Репутация: 2 Всего: 2 |
ну ясное дело что только те, которые являются частью интерфейса - это не суть важно, я к тому что оттуда эта привычка и пошла. Насчёт макросов - вообще утверждение спорно. как это не нужно? почему? мне кажется кому какой стиль написания нравится, тот так и пишет... при условии, что это находится в рамках разумного конечно. |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
||||
|
||||
| Master01 |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 89 Регистрация: 22.8.2007 Репутация: 2 Всего: 2 |
а почему? |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
потому что методы, которые являются частью com интерфейса, рекомендуется объявлять через макросы, для единообразия со сгенерированным по idl кодом
|
|||
|
||||
| Master01 |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 89 Регистрация: 22.8.2007 Репутация: 2 Всего: 2 |
а что вручную написать virtual HRESULT __stdcall - очень большая ошибка? |
|||
|
||||
| mes |
|
||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
дело в том , что __sdtcall предназначен для функций, а не для методов, и возможна такая реализация компилятора, где определенный посредством директивы __stdcall метод, будет не соответствовать реальному соглашению о вызове. Тогда как макрос STDMETHOD гарантирует соответствие. Добавлено @ 15:29
такая же как вместо этого написать virtual long __stdcall Это сообщение отредактировал(а) mes - 22.9.2008, 15:30 |
||||
|
|||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |