通过虚函数表访问private成员
通过虚函数表可以访问到对象的布局,通过函数指针可以运行函数,不论是private还是public,于是单继承、非virtual的demo如下:
-
#include <iostream>
-
-
class A
-
{
-
public:
-
A(): x(5) { }
-
-
private:
-
virtual void fun() { std::cout << "A::fun()" << std::endl; }
-
-
private:
-
int x;
-
};
-
-
class B: public A
-
{
-
public:
-
B(): y(3) { }
-
-
private:
-
virtual void fun() { std::cout << "B::fun()" << std::endl; }
-
-
private:
-
int y;
-
};
-
-
typedef void (*Fun)();
-
-
void PrintVTable(Fun* pVT)
-
{
-
Fun* pFun = pVT;
-
while( *pFun )
-
{
-
(*pFun)();
-
pFun ++;
-
}
-
}
-
-
void PrintMembers(int* pMembers)
-
{
-
std::cout << *pMembers << std::endl;
-
}
-
-
void PrintVTableAndMembers(B* ptr)
-
{
-
int* pAddress = (int*) ptr;
-
PrintVTable((Fun*) *pAddress);
-
pAddress ++;
-
-
PrintMembers(pAddress);
-
pAddress ++;
-
-
PrintMembers(pAddress);
-
pAddress ++;
-
}
-
-
void main(void)
-
{
-
B b;
-
-
PrintVTableAndMembers(&b);
-
-
system("pause");
-
}
如果是多继承 或者 继承方式用virtual,对象的布局是不一样的,可以参考下本文:http://yoyo.is-programmer.com/posts/10671.html
附,单继承非virtual方式的访问demo:
-
#include <iostream>
-
-
class A
-
{
-
public:
-
void f1() { std::cout << "A::f1()" << std::endl; }
-
void f2() { std::cout << "A::f2()" << std::endl; }
-
-
virtual void v1() { std::cout << "A::v1()" << std::endl; }
-
virtual void v2() { std::cout << "A::v2()" << std::endl; }
-
-
public:
-
int x;
-
};
-
-
class B: public A
-
{
-
public:
-
void f2() { std::cout << "B::f2()" << std::endl; }
-
-
void v2() { std::cout << "B::v2()" << std::endl; }
-
-
virtual void v3() { std::cout << "B::v3()" << std::endl; }
-
-
public:
-
int y;
-
};
-
-
class C: public B
-
{
-
public:
-
void f1() { std::cout << "C::f1()" << std::endl; }
-
void v1() { std::cout << "C::v1()" << std::endl; }
-
void v3() { std::cout << "C::v3()" << std::endl; }
-
-
public:
-
int z;
-
};
-
-
typedef void (*Fun)();
-
-
void PrintVTable(A* p)
-
{
-
int* pVFTable = (int*) (* ((int*)p) ); // 访问虚函数表
-
-
Fun* fun = (Fun*) pVFTable; // 移动到第一个虚函数
-
int iFunSize = 0;
-
while( *fun )
-
{
-
(*fun)(); // 执行函数指针所指向的内容
-
iFunSize ++;
-
fun = (Fun*) (pVFTable+iFunSize);
-
}
-
}
-
-
void PrintMember(A* p)
-
{
-
int* pMember = (int*) p;
-
for (int i = 1; i<=3; i++)
-
{
-
std::cout << (*(pMember+i)) << std::endl;
-
}
-
}
-
-
void main(void)
-
{
-
A* a = new C;
-
a->x = 10;
-
-
PrintVTable(a);
-
PrintMember(a);
-
-
C* c = (C*)a;
-
c->x = 100;
-
c->y = 80;
-
c->z = 50;
-
-
PrintVTable(c);
-
PrintMember(c);
-
-
system("pause");
-
}
多继承非virtual方式的访问demo:
-
#include <iostream>
-
-
class A
-
{
-
public:
-
virtual void fun(void) { std::cout << "A::fun()" << std::endl; }
-
-
public:
-
int x;
-
};
-
-
class B
-
{
-
public:
-
virtual void funB(void) { std::cout << "B::funB()" << std::endl; }
-
virtual void funC(void) { std::cout << "B::funC()" << std::endl; }
-
-
public:
-
int y;
-
};
-
-
class C: public A, public B
-
{
-
public:
-
void funC(void) { std::cout << "C::funC()" << std::endl; }
-
-
public:
-
int z;
-
};
-
-
typedef void (*Fun)();
-
-
void PrintVTable(Fun* fun)
-
{
-
while( *fun )
-
{
-
(*fun)();
-
fun++;
-
}
-
}
-
-
void PrintMembers(int* pMember)
-
{
-
std::cout << *pMember << std::endl;
-
}
-
-
void PrintVTableAndMembers(C* c)
-
{
-
int* pAddress = (int *) c;
-
for(int i=0; i<2; i++)
-
{
-
PrintVTable((Fun*)*pAddress);
-
pAddress ++;
-
PrintMembers(pAddress);
-
pAddress ++;
-
}
-
PrintMembers(pAddress);
-
}
-
-
void main(void)
-
{
-
C c;
-
c.x = 3;
-
c.y = 4;
-
c.z = 5;
-
-
PrintVTableAndMembers(&c);
-
-
system("pause");
-
}
-
#include <iostream>
-
-
class B1
-
{
-
public:
-
int x;
-
-
public:
-
void f1() { std::cout << "B1::f1()" << std::endl; };
-
-
virtual void v1() { std::cout << "B1::v1()" << std::endl; };
-
};
-
-
class B2
-
{
-
public:
-
int y;
-
-
public:
-
void f2() { std::cout << "B2::f2()" << std::endl; };
-
-
virtual void v2() { std::cout << "B2::v2()" << std::endl; };
-
};
-
-
class B3
-
{
-
public:
-
int z;
-
-
public:
-
void f3() { std::cout << "B3::f3()" << std::endl; };
-
-
virtual void v3() { std::cout << "B3::v3()" << std::endl; };
-
};
-
-
class D: public B1, public B2, public B3
-
{
-
public:
-
int a;
-
-
public:
-
virtual void v3() { std::cout << "D::v3()" << std::endl; };
-
-
virtual void vD() { std::cout << "D::vD()" << std::endl; };
-
};
-
-
typedef void (*Fun)();
-
-
void PrintVTable(Fun* pVT)
-
{
-
while( *pVT )
-
{
-
(*pVT) ();
-
pVT++;
-
}
-
}
-
-
void PrintMember(int* pMember)
-
{
-
std::cout << *pMember << std::endl;
-
}
-
-
void PrintVTableAndMembers(D* p)
-
{
-
int* pRoot = (int*) p;
-
-
for(int i=0; i<3; i++)
-
{
-
PrintVTable((Fun*)(int *)*pRoot);
-
pRoot ++;
-
PrintMember(pRoot);
-
pRoot ++;
-
}
-
-
PrintMember(pRoot);
-
}
-
-
void TestDynamicCast(D* d)
-
{
-
std::cout << "D : " << d << std::endl;
-
-
B1* b1 = d;
-
std::cout << "B1: " << b1 << std::endl;
-
-
B2* b2 = d;
-
std::cout << "B2: " << b2 << std::endl;
-
-
B3* b3 = d;
-
std::cout << "B3: " << b3 << std::endl;
-
}
-
-
void main(void)
-
{
-
D d;
-
d.a = 1;
-
d.x = 3;
-
d.y = 4;
-
d.z = 5;
-
-
PrintVTableAndMembers(&d);
-
-
TestDynamicCast(&d);
-
-
system("pause");
-
}
菱形继承的demo:
-
#include <iostream>
-
-
class A
-
{
-
public:
-
void funA() { std::cout << "A::funA()" << std::endl; }
-
-
virtual void vA() { std::cout << "A::vA()" << std::endl; }
-
-
public:
-
int i;
-
};
-
-
class B: virtual public A
-
{
-
public:
-
void funB() { std::cout << "B::funB()" << std::endl; }
-
-
virtual void vB() { std::cout << "B::vB()" << std::endl; }
-
-
public:
-
int x;
-
};
-
-
class C: virtual public A
-
{
-
public:
-
void funC() { std::cout << "C::funC()" << std::endl; }
-
-
virtual void vA() { std::cout << "C::vA()" << std::endl; }
-
-
virtual void vC() { std::cout << "C::vC()" << std::endl; }
-
-
public:
-
int y;
-
};
-
-
class D: public B, public C
-
{
-
public:
-
void funD() { std::cout << "D::funD()" << std::endl; }
-
-
virtual void vA() { std::cout << "D::vA()" << std::endl; }
-
-
virtual void vB() { std::cout << "D::vB()" << std::endl; }
-
-
virtual void vD() { std::cout << "D::vD()" << std::endl; }
-
-
public:
-
int z;
-
};
-
-
typedef void (*Fun)();
-
-
void PrintVTable(Fun* p)
-
{
-
while( *p )
-
{
-
(*p) ();
-
p ++;
-
}
-
}
-
-
void PrintMembers(int* p)
-
{
-
std::cout << *p << std::endl;
-
}
-
-
void PrintVTableAndMembers(D* d)
-
{
-
int* pRoot = (int*) d;
-
-
for(int i=0; i<2; i++)
-
{
-
PrintVTable((Fun*) *((int*)pRoot));
-
pRoot ++;
-
-
std::cout << "VbTable Address: " << *((int*) *pRoot) << std::endl;
-
pRoot ++;
-
-
PrintMembers(pRoot);
-
pRoot ++;
-
}
-
-
PrintMembers(pRoot);
-
pRoot ++;
-
-
PrintVTable((Fun*) *((int*)pRoot));
-
pRoot ++;
-
-
PrintMembers(pRoot);
-
}
-
-
void TestDynamicCast(D* d)
-
{
-
std::cout << "D: " << d << std::endl;
-
-
A* a = d;
-
std::cout << "A: " << a << std::endl;
-
-
B* b = d;
-
std::cout << "B: " << b << std::endl;
-
-
C* c = d;
-
std::cout << "C: " << c << std::endl;
-
}
-
-
void main(void)
-
{
-
D d;
-
d.i = 0;
-
d.x = 1;
-
d.y = 2;
-
d.z = 3;
-
-
PrintVTableAndMembers(&d);
-
-
TestDynamicCast(&d);
-
-
system("pause");
-
}