Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Таблица виртуальных функций  (Прочитано 10368 раз)
0 Пользователей и 1 Гость смотрят эту тему.
_IGOR_
Гость
« : 16-08-2008 11:42 » 

Выручайте! Да можно...
Хочу розобратса с структурой таблиц виртуальных функций в Borland C++
Моя задача:
Подменить адресс виртуальной функции класса на адресс функции вне класса.

Интерисует именно подмена адресса,а не вызов функции по ее адрессу.
Кому интересно даю код для розмышлений Внимание! Говорит и показывает...:
Код:
#include <iostream.h>
#include <conio.h>
class A
{
public:
virtual void F1(){ cout<<"Ok!";};
};
class B
{
public:
virtual void F1(){ cout<<"!!!!!!!!!!!!!!!!!!";};
};


typedef void(*FF)(void);
main()
{
clrscr();
A obj;
B bobj;
   
   cout << "VPTR's Address " << (int*)(&obj+0) << endl;
   cout << "VIRTUAL TABLE 's Address " << (int*)*(int*)(&obj+0) << endl; // Value of VPTR
   cout << "Value at first entry of VIRTUAL TABLE " << (int*)*(int*)*(int*)(&obj+0) << endl;

   FF Funk = (FF)*((int*)*(int*)(&obj+0)+0); // calling Virtual function
   
//**********************************************************************
   (FF)*((int*)*(int*)(&obj+0)+0)=(FF)*((int*)*(int*)(&bobj+0)+0);
//**********************************************************************   

 Funk();

getch();
}
« Последнее редактирование: 16-08-2008 12:05 от Finch » Записан
_IGOR_
Гость
« Ответ #1 : 16-08-2008 11:47 » 

  В даном примере я вызываю функцию класса по ее адрессу в ТАБЛИЦЕ ВИРТУАЛЬНЫХ ФУНКЦИЙ,
  не называя ее по имени.

  Программа полностью компилируетса , НО строчка заключенная между звездочками
  не дает ни какого результата (и адресс функции НЕ ПОДМЕНЯЕТ).
  Почему непонимаю!
 
ВЫРУЧАЙТЕ!
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #2 : 16-08-2008 12:05 » 

_IGOR_, Опиши для чего тебе это нужно. Может быть есть другие пути для решения задачи. Например функции обратного вызова.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #3 : 16-08-2008 19:04 » 

//**********************************************************************
   (FF)*((int*)*(int*)(&obj+0)+0)=(FF)*((int*)*(int*)(&bobj+0)+0);
//**********************************************************************   

Афигеть, что-то подобное я уже видел. ДУмаю Лёшка поможет разобраться с таким кастингом. Ага

_IGOR_, что ты понимаешь под "подменой адреса?"
Цитата
Интерисует именно подмена адресса,а не вызов функции по ее адрессу.

Хотя я больше согласен с Финчем, расскажи что ты хочешь. Очень похоже на решение уже решённой проблемы.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #4 : 16-08-2008 19:44 » 

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

Не будите спашяго дракона.
             Джаффар (Коша)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #5 : 17-08-2008 04:11 » 

а чё сразу Лёшка то ? ))

вот энто всё
Код:
FF Funk = (FF)*((int*)*(int*)(&obj+0)+0); // calling Virtual function
   
//**********************************************************************
   (FF)*((int*)*(int*)(&obj+0)+0)=(FF)*((int*)*(int*)(&bobj+0)+0);
//**********************************************************************   

заменяем на что то типа
Код:
FF Funk = (FF)&obj;
   
//**********************************************************************
   *((DWORD*)&obj)=*((DWORD*)&bobj);
//**********************************************************************   

проверять - не проверял
« Последнее редактирование: 17-08-2008 04:17 от Алексей1153++ » Записан

Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #6 : 18-08-2008 04:19 » 

вот код подмены виртуальной функции(кажется даже работает):
Код:
class A
{
public:
virtual void foo() = 0;
virtual ~A(){}
};

class B: public A
{
public:
virtual void foo() { std::cout << "B::foo" << std::endl; }
virtual ~B() {}
};

void Foo(B*)
{
std::cout << "Foo" << std::endl;
}

int _tmain(int argc, _TCHAR* argv[])
{

B b;
void *** v = reinterpret_cast<void***>(&b);
**v = &Foo;
A* a = &b;
a->foo();

return 0;
}

Код работает, НО при загрузке кода в память, область памяти, где хранятся виртуальные функции помечается, как RO так что все потуги идут лесом, вроде можно это обойти, но лично мне такие грязные хаки не нравятся, я не вижу не одной причины, так делать.
Записан

Странно всё это....
_IGOR_
Гость
« Ответ #7 : 18-08-2008 10:51 » 

Начнем по порядку:
   
   - Я должен решыть ету задачу в Borlnd C++ 3.1 [синий екранчик];
   - Если в классе есть виртуальная функция,то компилятор создает в начале обьекта класса
     ссил
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #8 : 18-08-2008 10:54 » 

_IGOR_, Вопрос остается в силе, для чего такой бубен тебе? Возьми поменьше и пляши сколько вздумается.

Я лично не вижу задачи, где нужно избегать стандартные средства языка программирования.
« Последнее редактирование: 18-08-2008 10:55 от Finch » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
_IGOR_
Гость
« Ответ #9 : 18-08-2008 11:00 » 

  Ету задачу задал мне преподователь во время учебного года и я ее не решил.
  И мне просто очень хочется ее добить до конца  Действовать надо быстро
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #10 : 18-08-2008 12:03 » 

Цитата: _IGOR_
Ету задачу задал мне преподователь во время учебного года и я ее не решил.
Если эту, то бредовая задачка. Какой смысл в "грязных хаках" объектно-ориентированной инфраструктуры языка программирования? Зачем ломать язык, когда можно просто использовать ООП?

В случае необходимости вызова разных функций-не членов, используя свойство виртуальности функций-членов, так можно просто их вызывать:

Код: (C++)
void f1() {}
void f2() {}

class X
{
public:
   virtual void m() { f1(); }
};

class Y: public X
{
public:
   virtual void m() { f2(); }
};

и не городить огород с расчётом адресов и возни с передачей this.
« Последнее редактирование: 18-08-2008 12:05 от dimka » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #11 : 19-08-2008 04:23 » 

dimka респект и уважуха Улыбаюсь а ларчик просто открывался

Хотя может задание звучит: руками поправить табличку.
« Последнее редактирование: 19-08-2008 04:37 от LogRus » Записан

Странно всё это....
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines