К вопросу о вопросах по C++
31/1/06 13:16Продолжаем набивать журнал контентом.
Что будет, если указателю на функцию-член присвоить указатель на виртуальный метод предка, а потом вызвать её на экземпляре потомка?
А для невиртуальной функции?
И на gcc, и на MSVC выдаёт одно и то же:
Вывод интересен: указатель на функцию-член хранит И индекс в VMT, И указатель на функцию. Ну и флаг, указывающий, что именно хранится.
Что будет, если указателю на функцию-член присвоить указатель на виртуальный метод предка, а потом вызвать её на экземпляре потомка?
А для невиртуальной функции?
#include <iostream>
class A
{
public:
virtual void f() { std::cout << "A::f()\n"; };
void g() { std::cout << "A::g()\n"; };
};
class B : public A
{
public:
virtual void f() { std::cout << "B::f()\n"; };
void g() { std::cout << "B::g()\n"; };
};
typedef void (A::*VirtualFunctionPointer) ();
int main()
{
A a;
B b;
B* pb = &b;
VirtualFunctionPointer p = &A::f;
(pb->*p) ();
p = &A::g;
(pb->*p) ();
return 0;
}
И на gcc, и на MSVC выдаёт одно и то же:
B::f()
A::g()Вывод интересен: указатель на функцию-член хранит И индекс в VMT, И указатель на функцию. Ну и флаг, указывающий, что именно хранится.
Tags:
fun
1/2/06 06:37 (UTC)Ко всему, еще есть одна особенность, насколько я знаю, указатель на функцию-член имеет жесткую привязку к типу(классу) в котором эта функция описана, но в этом примере в первом случае вызов (pb->*p) (); эквивалентен B::f()(так как B наследник класса A), т.е. можно сказать, что сработал механизм преобразования имени виртуальной функции в индекс в виртуальной таблице. Для второго присваивания все более проще, при присваивании p = &A::g, а сам p является просто "указателем" на функции-члены класса A и только A, то поэтому и произошел вызов функции A::g(), причем его скорее всего можно интерпритировать как pb->A::g();
P.S. Все вышенаписанное сугубо мое ИМХО :-)
(no subject)
1/2/06 06:42 (UTC)(no subject)
1/2/06 06:52 (UTC)(no subject)
1/2/06 06:53 (UTC)(no subject)
1/2/06 07:20 (UTC)(no subject)
1/2/06 07:52 (UTC)P.S. наверно я вас достал своими постами, звыняйте... :-)