Форум программистов, компьютерный форум CyberForum.ru

Грязный хук. - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.86
Genius Ignat
1233 / 771 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
01.03.2010, 11:17     Грязный хук. #1
Провёл не большой анализ по одному коду, и выянил не которые особенности,
о которых не пишут в книгах о языке C++.
Это я узнал из книги INside COM.

Также помню не в тему спор завёл где то на форме, про виртуальный деструктор и
где его надо прописывать.
Правильнее и безопаснее прописывать конечно везде, если не брать концепцию COM.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream.h>
class Abstract {
public:
/*Абстрактному классу не нужен виртуальный деструктор потому что Release может действовать и без него,
*/
virtual long Release() = 0;
};
class MyClass: public Abstract  {
public:
    MyClass(){ cout<<"Create MyClass\n"; }
    virtual ~MyClass() {cout<<"Destroy\n"; }
    
virtual long Release(){
/*подразумивается как delete obj, верно ли я предполагаю, поэтому деструктор вызывается с нужного места  иерархии: тоесть с производного класса.
*/  delete this;                
             return 0;
    }
};
 
 
int main(){
MyClass  *obj = new MyClass;
Abstract *aobj = obj;
aobj->Release();
//delete aobj; не сработает так как в базовом нет виртуального деструктора.
return 0;
}
Тогда получается COM компонент явно через delete( к указателю базового класса) не удалить,
так как в базовом классе отстутсвует виртуальный деструктор.

Я то знаю почему надо что бы delete не работало, мне это известно.

Я просто хочу узнать у более опытных прогеров верно ли мое предположение о том как действует
Release():
/*подразумивается как delete obj, верно ли я предполагаю, поэтому деструктор вызывается с нужного места иерархии: тоесть с производного класса.
*/
Или применяется ещё что то.
Ответьте пожалейста, заранее благодарен.
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.03.2010, 11:17     Грязный хук.
Посмотрите здесь:

Delphi WinAPI Хук на DblClick
Хук C++ Builder
WordPress Хук
C++ Глобальный хук клавиатуры
Грязный фон HTML, CSS

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
01.03.2010, 11:52     Грязный хук. #2
Я видел только реализации Release в виде функионлаьно-подобного дефайна, в котором на самом деле упакован delete.
Genius Ignat
1233 / 771 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
01.03.2010, 12:32  [ТС]     Грязный хук. #3
Версия Release() написана не в полной мере, так как цель этой темы имеенно момент
delete this;
Как организованая модель клиент-> интерфейс-> компонент. я тут не обсуждаю.


Я видел только реализации Release в виде функионлаьно-подобного дефайна, в котором на самом деле упакован delete.
Эта вещь не подходит для данного мною контекста.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16828 / 5249 / 321
Регистрация: 30.03.2009
Сообщений: 14,136
Записей в блоге: 26
01.03.2010, 14:06     Грязный хук. #4
Вообще вызывать delete внутри метода класса - не есть хорошо. Это уже на форуме где-то обсуждалось. А чего ты хочешь этим кодом добиться в конечном итоге?

Добавлено через 18 секунд
Вернее, чего хочешь добиться - понятно. Непонятно зачем
Genius Ignat
1233 / 771 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
01.03.2010, 14:33  [ТС]     Грязный хук. #5
Вообще вызывать delete внутри метода класса - не есть хорошо.
Microsoft(r) начхать на это.
Ссылку давать не стоит.

В данном случае delete применимо только через указатель производного.

Мне интерсно как проихсодит правильное удаление: вызов деструктора.
Тип объекта определяется через this или как.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16828 / 5249 / 321
Регистрация: 30.03.2009
Сообщений: 14,136
Записей в блоге: 26
01.03.2010, 14:41     Грязный хук. #6
Ты delete вызываешь в методе класса MyClass, в нём this имеет тип MyClass*, а потому и деструктор вызывается от класса MyClass

> Microsoft(r) начхать на это
А потом на свет появляется глючный софт, который перестаёт работать после обновлений системных библиотек или ОС

Я не очень понимаю, чем тебя не устраивает написать деструктор в базовом классе и нормально удалять объекты без извратов?
CyBOSSeR
Эксперт C++
 Аватар для CyBOSSeR
2294 / 1664 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
01.03.2010, 15:03     Грязный хук. #7
Цитата Сообщение от Evg Посмотреть сообщение
Вообще вызывать delete внутри метода класса - не есть хорошо.
С чем связано такое утверждение? Взять те же объекты, непосредственно поддерживающие счетчик ссылок - удаление как раз таки производится именно путем вызова delete this в операции уменьшения счетчика ссылок.
Genius Ignat
1233 / 771 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
01.03.2010, 15:22  [ТС]     Грязный хук. #8
А потом на свет появляется глючный софт, который перестаёт работать после обновлений системных библиотек или ОС.
Умнее и универсальнее Microsoft(r) Direct Show я ничего не видел.

Добавлено через 6 минут
вызова delete this в операции уменьшения счетчика ссылок.
И больше ни как, потому что delete не может знать сколько указателей указывают на одну область памяти.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16828 / 5249 / 321
Регистрация: 30.03.2009
Сообщений: 14,136
Записей в блоге: 26
01.03.2010, 15:24     Грязный хук. #9
Цитата Сообщение от CyBOSSeR Посмотреть сообщение
С чем связано такое утверждение? Взять те же объекты, непосредственно поддерживающие счетчик ссылок - удаление как раз таки производится именно путем вызова delete this в операции уменьшения счетчика ссылок.
Компилятор Си++ помимо кода, который ты написал ручками, строит ещё и скрытые коды. Нехилый паравоз может вылезти из кода проводки исключительных ситуаций. Понятное дело, что если ограничиться только виндами и только микрософтовским компилятором, то проблем, скорее всего, не будет, потому как там почти наверняка работает что-ти типа libunwind (т.е. компилятор вообще ничего не строит по части раскрутки стека). Но можно ли считать подобный код переносимым на 100% - вопрос

Добавлено через 1 минуту
Цитата Сообщение от CyBOSSeR Посмотреть сообщение
удаление как раз таки производится именно путем вызова delete this в операции уменьшения счетчика ссылок.
Может я мысль неправильно понял, но мне казалось, что надо в деструкторе уменьшать счётчик, а не в процедуре уменьшения счётчика вызывать delete
CyBOSSeR
Эксперт C++
 Аватар для CyBOSSeR
2294 / 1664 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
01.03.2010, 15:32     Грязный хук. #10
Цитата Сообщение от Evg Посмотреть сообщение
Может я мысль неправильно понял, но мне казалось, что надо в деструкторе уменьшать счётчик, а не в процедуре уменьшения счётчика вызывать delete
Зачем уменьшать счетчик если объект фактически уже удален?

Обычно объекты, поддерживающие счетчик ссылок имеют пару методов для уменьшения/увеличения счетчика ссылок. В методе уменьшения счетчика при его обнулении происходит удаление объекта.
Простой пример:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class ClassWithRefCounter
{
public:
  ClassWithRefCounter()
  : ref_count(1)
  {}
   
  void AddRef()
  {
    ++ref_count;
  }
 
  void Release()
  {
    if(--ref_count == 0)
      delete this;
  }
 
private:
  int ref_count;
}
Клиенты при создании новой ссылки на объект вызывают AddRef, при удалении ссылки Release.
Genius Ignat
1233 / 771 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
01.03.2010, 15:35  [ТС]     Грязный хук. #11
переносимым на 100% - вопрос
Не беспокойся COM скоро и на Lunix переедет.
Evg:
Ты же не знаешь что такое COM поэтому тему лучше не раздувать по пусту,
тем более что ответ я уже получил.

Может я мысль неправильно понял, но мне казалось, что надо в деструкторе уменьшать
счётчик
Такой хук в деструкторах, делают "smatr_ptr" интеллектуальные указатели.
CyBOSSeR скорее всего имеет ввиду компоненты COM.
CyBOSSeR
Эксперт C++
 Аватар для CyBOSSeR
2294 / 1664 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
01.03.2010, 15:39     Грязный хук. #12
Цитата Сообщение от Genius Ignat Посмотреть сообщение
CyBOSSeR скорее всего имеет ввиду компоненты COM.
Объекты, поддерживающие счетчик ссылок используется далеко не только в COM.
Genius Ignat
1233 / 771 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
01.03.2010, 15:46  [ТС]     Грязный хук. #13
Такой хук в деструкторах, делают "smatr_ptr" интеллектуальные указатели.
Без этого ни как, иначе возможно удаление объекта во время его использования,
из - за того что указатели указывают на одну область памяти.

Добавлено через 5 минут
Объекты, поддерживающие счетчик ссылок используется далеко не только в COM
Ну скорее всего там где они используются, картина аналогична картине COM,

так как использование указателей которые указывают на одну область памяти, должно
быть с счетчиком ссылок, иначе будет не безопасно.
Это моё субъективное мнение.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16828 / 5249 / 321
Регистрация: 30.03.2009
Сообщений: 14,136
Записей в блоге: 26
01.03.2010, 16:10     Грязный хук. #14
После примера, я понял, что имелось в виду под "счётчиком ссылок"

Добавлено через 9 минут
Цитата Сообщение от CyBOSSeR Посмотреть сообщение
Простой пример:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class ClassWithRefCounter
{
public:
  ClassWithRefCounter()
  : ref_count(1)
  {}
   
  void AddRef()
  {
    ++ref_count;
  }
 
  void Release()
  {
    if(--ref_count == 0)
      delete this;
  }
 
private:
  int ref_count;
}
Метод Release нельзя вызывать из другого метода класса. Этого, на мой взгляд, достаточно для того, чтобы такое действие считалось невалидным
Genius Ignat
1233 / 771 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
01.03.2010, 16:15  [ТС]     Грязный хук. #15
нельзя вызывать из другого метода класса
Наверное произойдет что то страшное.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16828 / 5249 / 321
Регистрация: 30.03.2009
Сообщений: 14,136
Записей в блоге: 26
01.03.2010, 16:27     Грязный хук. #16
С точки зрения стандарта

Добавлено через 10 минут
Правда в стандарте ничего по этому поводу не нашёл
CyBOSSeR
Эксперт C++
 Аватар для CyBOSSeR
2294 / 1664 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
01.03.2010, 16:34     Грязный хук. #17
Цитата Сообщение от Evg Посмотреть сообщение
Метод Release нельзя вызывать из другого метода класса. Этого, на мой взгляд, достаточно для того, чтобы такое действие считалось невалидным
Метод Release не предназначен для вызова из методов самого класса, у него другое назначение - его должны вызывать клиенты, когда необходимость в ссылке на объект отпадает.
Такой подход как раз таки используется в технологии COM.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16828 / 5249 / 321
Регистрация: 30.03.2009
Сообщений: 14,136
Записей в блоге: 26
01.03.2010, 16:41     Грязный хук. #18
Цитата Сообщение от CyBOSSeR Посмотреть сообщение
Метод Release не предназначен для вызова из методов самого класса, у него другое назначение - его должны вызывать клиенты, когда необходимость в ссылке на объект отпадает
Я сейчас о говорю не о самой технике, а о том, насколько допустимым считается подобное действие с точки зрения стандарта. У меня сейчас что-то типа "ж..й чую, что литр, но доказать не могу"
CyBOSSeR
Эксперт C++
 Аватар для CyBOSSeR
2294 / 1664 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
01.03.2010, 17:03     Грязный хук. #19
Цитата Сообщение от Evg Посмотреть сообщение
Я сейчас о говорю не о самой технике, а о том, насколько допустимым считается подобное действие с точки зрения стандарта.
По поводу delete this, никаких упоминаний в стандарте нет.
Это легальная операция, если память выделена с помощью оператора new и никаких обращений к указателю this после вызова delete this не последует.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16828 / 5249 / 321
Регистрация: 30.03.2009
Сообщений: 14,136
Записей в блоге: 26
01.03.2010, 18:08     Грязный хук. #20
Цитата Сообщение от CyBOSSeR Посмотреть сообщение
Это легальная операция, если память выделена с помощью оператора new и никаких обращений к указателю this после вызова delete this не последует.
Она условно легальная. Т.е. такой метод можно вызывать только вне класса. А такое ограничение наводит на подозрение о нелегальности
Yandex
Объявления
01.03.2010, 18:08     Грязный хук.
Ответ Создать тему
Опции темы

Текущее время: 12:08. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru