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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 29, средняя оценка - 4.72
Blazik
0 / 0 / 0
Регистрация: 21.06.2012
Сообщений: 13
#1

Вызов виртуальной функции по указателю - C++

21.06.2012, 23:41. Просмотров 4420. Ответов 30
Метки нет (Все метки)

Суть в том, что преподаватель дал задание на защиту курсовой: вызов по указателю виртуальной функции из ТВР, искал в интернете, наткнулся на этом форуме на то, что доступа прямого к таблице нет, может кто-то подсказать или подкинуть статью/литературу, время до утра, поэтому буду благодарен за оперативность.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.06.2012, 23:41
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Вызов виртуальной функции по указателю (C++):

Вызов виртуальной функции по нулевому указателю - C++
struct A { int sum1(int a, int b) { return a+b; } virtual int sum2(int a, int b) { return a+b; } }; int main() { ...

Вызов функции по указателю из класса - C++
Такой расклад. Допустим имеем код: #include <iostream> using namespace std; template <class _Tp> class my_mem_fun_t { ...

Вызов виртуальной функции - C++
Здравствуйте, есть код: #include <iostream> using namespace std; class A{ public: virtual void doIt() {cout << "1";} ...

Не работает вызов виртуальной функции из класса потомка - C++
Есть код: #include <iostream> #include <vector> #include <list> #include <algorithm> #include <string> #include <sstream> ...

Вызов виртуальной функции через указатель на базовый класс - C++
Всем привет! Помогите пожалуйста разобраться с вызовом виртуальной функции в программе. В моей программе требуется организовать класс...

Вызов виртуальной функции vs несколько dynamic_cast подряд: что быстрее? - C++
Нужно максимально оптимизировать программу вот и пал выбор: лучше сделать чтобы вызывались виртуальные функции или же чтобы было четыре...

30
DU
1484 / 1130 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
22.06.2012, 01:10 #2
то, что вам предлагают - хак. чтобы вызвать функцию через таблицу виртуальных функций, нужно знать где она находится и как устроено. и то и другое зависит от компилятора и нужно либо найти документацию, либо экспериментами всякими попробовать это определить. таблица может находится в начале объекта или в конце. плюс возможно она рассположена с выравниванием. в таблице функции вроде тоже могут быть в неопределенном порядке. если так, то тут тоже нужно экспериментами искать индекс нужной функции.
В общем очень странное требование какое-то. Может вы что-то не так поняли и от вас хотят просто вызов виртуальной функции через указатель на объект?

И что такое ТBP?
1
Blazik
0 / 0 / 0
Регистрация: 21.06.2012
Сообщений: 13
22.06.2012, 01:20  [ТС] #3
Таблица Виртуальных Функций, опечатался))
Ну то, что я написал это изначальная формулировка, потом, конечно, я встречный вопрос задал "просто по указателю вызвать виртуальную функцию", он ответил да. Скажем так преподаватель интересный сам по себе и кинул фразу "хочу увидеть реализацию, ну или хотя бы попытку", возможно действительно стоит не морочиться на таблице, думаю такое даже он бы не загнул, а по указателям на виртуальные функции, если можете подкиньте инфу или кусок кода, хотя бы абстрактный, спасибо, что помогли убедиться в понимании задачи и проблемах ее даже теоретической реализации))
0
DU
1484 / 1130 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
22.06.2012, 01:31 #4
Вот найдите в сети эту книжку:
Наиболее эффективное использование C++. 35 новых рекомендаций по улучшению ваших программ и проектов
http://rsdn.ru/res/book/cpp/most_effective_cpp.xml
Правило 24. Там штук 10 страниц. В ней немного расписано о том, как происходит вызов нужной виртуальной функции, где она может расспологатся и т.п.
0
Paporotnik
383 / 227 / 7
Регистрация: 06.07.2011
Сообщений: 512
22.06.2012, 01:38 #5
http://kaisar-haque.blogspot.com/200...ual-table.html для VC++.
1
dima koz
23 / 17 / 1
Регистрация: 05.06.2012
Сообщений: 72
Записей в блоге: 5
22.06.2012, 01:41 #6
см.скрин
0
Миниатюры
Вызов виртуальной функции по указателю  
CyBOSSeR
Эксперт С++
2307 / 1677 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
22.06.2012, 01:55 #7
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Blazik, все просто:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
 
class Virtual {
public:
  virtual void Method() {
    std::cout << "Aha!" << std::endl;
  }
};
 
typedef void (*FunctionPtr)();
 
int main() {
  Virtual object;
  FunctionPtr* vtable = *(FunctionPtr**)(&object);
  vtable[0]();
}
Проверено в GCC 4.7.

Добавлено через 4 минуты
Вот пример вызова метода, обращающегося к this:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
 
class Virtual {
private:
  int field;
 
public:
  Virtual() : field(100) { }
 
  virtual void Method() {
    std::cout << "Field value is: " << field << std::endl;
  }
};
 
typedef void (*FunctionPtr)(Virtual*);
 
int main() {
  Virtual object;
  FunctionPtr* vtable = *(FunctionPtr**)(&object);
  vtable[0](&object);
}
8
Blazik
0 / 0 / 0
Регистрация: 21.06.2012
Сообщений: 13
22.06.2012, 02:04  [ТС] #8
Подумал, вспомнил, что преподаватель объяснял про таблицу, в которой расположены адреса, все же требуется работа с таблицей значит, но всем спасибо, возможно поможет статья на английском.
0
CyBOSSeR
Эксперт С++
2307 / 1677 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
22.06.2012, 02:06 #9
Blazik, постом выше примеры вызова вирутальных методов напрямую через vtable.
0
Blazik
0 / 0 / 0
Регистрация: 21.06.2012
Сообщений: 13
22.06.2012, 02:41  [ТС] #10
CyBOSSeR, да-да, сейчас как раз разбираю этот код

Добавлено через 29 минут
CyBOSSeR, большое спасибо, дополнил код для наглядности происходящего в таблице при использовании наследующих классов, очень помогло.
0
Jupiter
Каратель
Эксперт С++
6566 / 3987 / 227
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
22.06.2012, 14:08 #11
Цитата Сообщение от CyBOSSeR Посмотреть сообщение
Вот пример вызова метода, обращающегося к this:
Что-то gcc хитрит, какое всё-таки у него соглашение вызовов для методов класса? В MSVS2010 этот код тоже работает, но при выводе значения поля field выводит 0 вместо 100.
Немного переделанный код CyBOSSeR
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
#include <iostream>
 
class Virtual {
private:
  int field;
 
public:
  Virtual() : field(100) { }
 
  virtual void Method() {
    std::cout << "Field value is: " << field << std::endl;
  }
};
 
typedef void (*FunctionPtr)();
 
int main() {
  Virtual object;
  FunctionPtr* vtable = *(FunctionPtr**)(&object);
  
  asm("movl $1, %%ecx;" : : "r"(&object) : "%ecx");
 
  vtable[0]();
}
Через регистры отрабатывает и в gcc-4.7.0 и
MSVS2010
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
#include <iostream>
 
class Virtual {
private:
  int field;
 
public:
  Virtual() : field(100) { }
 
  virtual void Method() {
    std::cout << "Field value is: " << field << std::endl;
  }
};
 
typedef void (*FunctionPtr)();
 
int main() {
  Virtual object;
  FunctionPtr* vtable = *(FunctionPtr**)(&object);
  Virtual* p = &object;
  _asm 
  {
      mov ecx, p
  }
  vtable[0]();
}
1
CyBOSSeR
Эксперт С++
2307 / 1677 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
23.06.2012, 00:13 #12
Ладно, с виртуальными функциями все понятно, вопрос где RTTI хранится. Всегда думал (и продолжаю), что одним из указателей в таблице виртуальных функций является указатель на RTTI, но вчера с наскока методом тыка, найти ничего внятного найти не удалось. Надо посмотреть реализацию typeid.
0
DU
1484 / 1130 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
23.06.2012, 02:13 #13
рассположение зависит от компилятора. чтобы узнать наверняка, нужно задиассемблировать строку получения указателя на type_info.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
 
class Base
{
public:
  virtual ~Base() {}
};
 
class Der : public Base
{
};
 
int main(int argc, char argv[])
{
  Der der;
  Base& rBase = der;
  const std::type_info* pTypeInfo = &typeid(rBase);
  std::cout << "address of typeinfo for " << pTypeInfo->name() << " = " << pTypeInfo << std::endl;
  return 0;
}
В студии эта строка в дизасме выглядит так:
// const std::type_info* pTypeInfo = &typeid(rBase);
00414772 mov eax,dword ptr [ebp-20h]
00414775 push eax
00414776 call @ILT+50(___RTtypeid) (411037h)
0041477B add esp,4
0041477E mov dword ptr [ebp-2Ch],eax

Т.е. идет вызов функции ___RTtypeid с передачей ей указателя на объект. Студия так же говорит, что она в файле rtti.cpp. Вот что-то похожее нашел тут:
http://code.google.com/p/ontl/source...rtti.cpp?r=741
Вот кому нужно - попробуйте разобратся. Код достаточно хитрый. Наверно из-за того, что нужно учитывать всякие множественные наследования + всякие другие провреки
1
CyBOSSeR
Эксперт С++
2307 / 1677 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
23.06.2012, 02:27 #14
С GCC в простейшем случае все просто:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <typeinfo>
 
class Virtual {
public:
    virtual void Method() { }
};
 
typedef const std::type_info* TypeInfoPtr;
 
int main() {
    Virtual object;
    TypeInfoPtr* table = *(TypeInfoPtr**)(&object);
    std::cout << (*(table - 1))->name() << std::endl;
}
[cybosser@cybosserpc development]$ g++ test.cpp -o test
[cybosser@cybosserpc development]$ ./test
7Virtual
0
Blazik
0 / 0 / 0
Регистрация: 21.06.2012
Сообщений: 13
23.06.2012, 02:45  [ТС] #15
ну в общем пришел я с кодом, а меня отослали куда подальше, ну по крайней мере теперь есть четкая задача, и как минимум я должен дать преподавателю четкий ответ на вопрос - где в объекте класса находится указатель на виртуальную таблицу)
0
23.06.2012, 02:45
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
23.06.2012, 02:45
Привет! Вот еще темы с ответами:

вызов конструктора, по указателю на объект - C++
class qwe { public: qwe() {} qwe(char * name, int a, int b):_name(strdup(name)), _a(a), _b(b) {} private: char * _name; ...

Вызов динамического метода класса по указателю на объект класса - C++
Как это можно сделать? И хотелось бы как можно проще.

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

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


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

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

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