Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.86
Genius Ignat
1237 / 775 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
#1

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

01.03.2010, 11:17. Просмотров 1845. Ответов 32
Метки нет (Все метки)

Провёл не большой анализ по одному коду, и выянил не которые особенности,
о которых не пишут в книгах о языке 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, верно ли я предполагаю, поэтому деструктор вызывается с нужного места иерархии: тоесть с производного класса.
*/
Или применяется ещё что то.
Ответьте пожалейста, заранее благодарен.
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.03.2010, 11:17
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Грязный хук. (C++):

Глобальный хук клавиатуры - C++
Привет. Мне нужно сделать глобальный хук клавиатуры, но я не знаю как. В интернете примеров на C++ мало и все не работают, потому что люди...

Глобальный хук. Довести до ума - C++
Здравствуйте, решил изучить механизмы хуков, почитал статьи. Появились вопросы. Вот собственно если делать глобальный хук, то функцию...

Грязный фон - HTML, CSS
Как вы верстаете страницы с фоном &quot;грязными пятнами&quot; типа того, что в приложенной картинки? Я обычно мучаю дизайнеров, чтоб он вырезал мне...

Хук - C++ Builder
MSG msg; while(GetMessage(&amp;msg,NULL,0,0)) TranslateMessage(&amp;msg), DispatchMessage(&amp;msg); switch(msg.wParam) { case WM_LBUTTONUP:...

Хук - WordPress
Добрый день. Питаюсь отправить админу письмо при публикации поста пример ( add_action('publish_post', 'Моя функцыя')). При публикации поста...

Хук на C# (Hook on C#) - C#
добрый день. знаю на форуме много тем про всякие хуки клавиатуры или мыши, но вирусные программы меня не интересуют, я хотел бы узнать как...

32
taras atavin
3571 / 1755 / 91
Регистрация: 24.11.2009
Сообщений: 27,567
01.03.2010, 11:52 #2
Я видел только реализации Release в виде функионлаьно-подобного дефайна, в котором на самом деле упакован delete.
0
Genius Ignat
1237 / 775 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
01.03.2010, 12:32  [ТС] #3
Версия Release() написана не в полной мере, так как цель этой темы имеенно момент
delete this;
Как организованая модель клиент-> интерфейс-> компонент. я тут не обсуждаю.


Я видел только реализации Release в виде функионлаьно-подобного дефайна, в котором на самом деле упакован delete.
Эта вещь не подходит для данного мною контекста.
0
Evg
Эксперт CАвтор FAQ
18467 / 6517 / 455
Регистрация: 30.03.2009
Сообщений: 18,200
Записей в блоге: 29
01.03.2010, 14:06 #4
Вообще вызывать delete внутри метода класса - не есть хорошо. Это уже на форуме где-то обсуждалось. А чего ты хочешь этим кодом добиться в конечном итоге?

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

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

Мне интерсно как проихсодит правильное удаление: вызов деструктора.
Тип объекта определяется через this или как.
0
Evg
Эксперт CАвтор FAQ
18467 / 6517 / 455
Регистрация: 30.03.2009
Сообщений: 18,200
Записей в блоге: 29
01.03.2010, 14:41 #6
Ты delete вызываешь в методе класса MyClass, в нём this имеет тип MyClass*, а потому и деструктор вызывается от класса MyClass

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

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

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

Добавлено через 1 минуту
Цитата Сообщение от CyBOSSeR Посмотреть сообщение
удаление как раз таки производится именно путем вызова delete this в операции уменьшения счетчика ссылок.
Может я мысль неправильно понял, но мне казалось, что надо в деструкторе уменьшать счётчик, а не в процедуре уменьшения счётчика вызывать delete
0
CyBOSSeR
Эксперт С++
2306 / 1676 / 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.
0
Genius Ignat
1237 / 775 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
01.03.2010, 15:35  [ТС] #11
переносимым на 100% - вопрос
Не беспокойся COM скоро и на Lunix переедет.
Evg:
Ты же не знаешь что такое COM поэтому тему лучше не раздувать по пусту,
тем более что ответ я уже получил.

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

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

так как использование указателей которые указывают на одну область памяти, должно
быть с счетчиком ссылок, иначе будет не безопасно.
Это моё субъективное мнение.
0
Evg
Эксперт CАвтор FAQ
18467 / 6517 / 455
Регистрация: 30.03.2009
Сообщений: 18,200
Записей в блоге: 29
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 нельзя вызывать из другого метода класса. Этого, на мой взгляд, достаточно для того, чтобы такое действие считалось невалидным
1
Genius Ignat
1237 / 775 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
01.03.2010, 16:15  [ТС] #15
нельзя вызывать из другого метода класса
Наверное произойдет что то страшное.
0
01.03.2010, 16:15
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.03.2010, 16:15
Привет! Вот еще темы с ответами:

Хук клавиатуры - C#
Доброго времени суток, я пытаюсь сделать хук клавиатуры столкнулся с таким вопросом. Как сделать что бы в лог записывался читаемый текст...

Хук на ZwEnumerateKey - Программирование драйверов
Добрый день, помогите советом. Есть у меня один драйвер, который перехватывает функцию ZwEnumerateKey и скрывает определенные ключи в...

Хук клавиатуры - C++ WinAPI
Нужно написать глобальный хук для клавиатуры. Сам хук у меня уже есть, но не могу никак проверить введено ли ключевое слово. Например, если...

Хук на процесс - C++ WinAPI
Добрый день. Подскажите, как установить хук на отдельный процесс, к примеру на Mozilla Firefox. А если есть возможность, приведите...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.