LINUX.ORG.RU

Укозатель на функцию член


0

0

class A {
	public:
		A() { a = 1111; }
		virtual void f() { cout << "aF" << endl; }
		virtual void g() { cout << "gF" << endl; }
		virtual void h() { cout << "hF" << endl; }
		virtual void i() { cout << "iF" << endl; }
	public:
		int a;
};
		
typedef void (A::*pfA)();
typedef void (*pf)();

int main(int argc, char *argv[])
{
	A obA;
	pfA *p;	
	/*long *vtbl = (long*)&obA;
	p = (pfA*)vtbl[0];
 	(obA.*p[0])();*/
        cout << sizeof(pf) << '\t' << sizeof(pfA) << endl;
  	return 0;
}

#g++ -m32 test.cpp -o test
#./test
4 8

Почему на функцию члензанимет 8 байт.

Спасибо.
anonymous

Будем рассуждать логически. 8 = 4+4. => 
Там живет еще один указатель. Указатель на объект отпадает, так как
он извращенно передается как параметр при вызове. Остается что-то на подобие TVM. Провереям:

#include <iostream>

using namespace std;

class A { public: virtual void f()  { cout << "A::F" << endl; } };

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

int main(int argc, char *argv[]) {
    void (A::*pf)();
    pf = &A::f;
    A *a = new B();
    (a->*pf)();
    delete a;
}

У меня печатает B::f


ival ★★
()
Ответ на: комментарий от anonymous

Еще не много подумал. Понял что прогнался по поводу 2 указателей.

Поскольку TVM должно быть можно получить по указалелю.

В типе указателя на метод нет нислова по поводу виртуальный этот метод или нет. => Скорее всего в реальности в указатель входит флаг того является ли он virtual или нет + для virtual хранится смещение относительно TVM, а для статического - указатель на функцию.

По этому размер должен быть по любому больше sizeof(void*)

ival ★★
()
Ответ на: комментарий от ival

s/для статического/для не виртуального/

Запутался в терминологии

ival ★★
()
Ответ на: комментарий от ival

А разве есть смысол в флаге?
Например:
void g(A* ob)
{
   ob->f();
}

если f виртуальная то получем (*(ob->vtbl[0]))(ob) , а если не
виртуалбная то просто f(ob).

Всеравно не ясно зачем нужны еще 4 байта?

anonymous
()
Ответ на: комментарий от anonymous

>если f виртуальная то получем (*(ob->vtbl[0]))(ob) , а если не виртуалбная то просто f(ob).

Если есть возможность определить это при компиляции, то нет

>Всеравно не ясно зачем нужны еще 4 байта?

Ну дык это должно решаться в Run Time.

Как должен выглядеть код функции:

void func (void(A::*pf)(), A* x) { (x->*pf)();}

ival ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.