程序1
#include <iostream>
using namespace std;
class Base1
{
public:
Base1()
{
m_length=1;
m_width=2;
}
virtual void f(void)
{
cout<<"Base1::f()"<<endl;
}
virtual void g(void)
{
cout<<"Base1::g()"<<endl;
}
virtual void h(void)
{
cout<<"Base1::h()"<<endl;
}
private:
int m_length;
int m_width;
};
class Base2
{
public:
Base2()
{
m_length=3;
m_width=4;
}
virtual void f(void)
{
cout<<"Base2::f()"<<endl;
}
virtual void g(void)
{
cout<<"Base2::g()"<<endl;
}
virtual void h(void)
{
cout<<"Base2::h()"<<endl;
}
private:
int m_length;
int m_width;
};
class Derived:public Base1,public Base2
{
public:
virtual void f(void)
{
cout<<"Derived::f()"<<endl;
}
virtual void k(void)
{
cout<<"Derived::k()"<<endl;
}
};
int main()
{
typedef void (*FUN)(void );
FUN func=NULL;
Derived d;
cout<<"member table address "<<(int*)(&d)<<endl;
cout<<"data member are follows:"<<endl;
cout<<*((int*)(&d)+1)<<endl;
cout<<*((int*)(&d)+2)<<endl;
cout<<*((int*)(&d)+4)<<endl;
cout<<*((int*)(&d)+5)<<endl;
cout<<"The two vptr address:"<<endl;
cout<<"the first vptr address "<<((int*)&d)<<endl;
func=(FUN)*((int*)*((int*)(&d)));
func();
func=(FUN)*((int*)*(int*)(&d)+1);
func();
func=(FUN)*((int*)*(int*)(&d)+2);
func();
func=(FUN)*((int*)*(int*)(&d)+3);
func();
cout<<endl;
cout<<"the second vptr address "<<(int*)&d+3<<endl;
func=(FUN)*((int*)*((int*)(&d)+3));
func();
func=(FUN)*((int*)*((int*)(&d)+3)+1);
func();
func=(FUN)*((int*)*((int*)(&d)+3)+2);
func();
func=(FUN)*((int*)*((int*)(&d)+3)+3);
func(); //运行时出错,非法访问,derived::k存放在Base1的虚函数表中
return 0;
}
运行结果:
member table address 0x22ff40
data member are follows:
1
2
3
4
The two vptr address:
the first vptr address 0x22ff40
Derived::f()
Base1::g()
Base1::h()
Derived::k()
the second vptr address 0x22ff4c
Derived::f()
Base2::g()
Base2::h()
Process returned -1073741819 (0xC0000005) execution time : 2.531 s
Press any key to continue.
程序2
#include <iostream>
using namespace std;
class Base1
{
public:
Base1()
{
m_length=1;
m_width=2;
}
virtual void f(void)
{
cout<<"Base1::f()"<<endl;
}
virtual void g(void)
{
cout<<"Base1::g()"<<endl;
}
virtual void h(void)
{
cout<<"Base1::h()"<<endl;
}
private:
int m_length;
int m_width;
};
class Base2
{
public:
Base2()
{
m_length=3;
m_width=4;
}
virtual void f(void)
{
cout<<"Base2::f()"<<endl;
}
virtual void g(void)
{
cout<<"Base2::g()"<<endl;
}
virtual void h(void)
{
cout<<"Base2::h()"<<endl;
}
private:
int m_length;
int m_width;
};
class Derived:public Base2,public Base1 /*修改处*/
{
public:
virtual void f(void)
{
cout<<"Derived::f()"<<endl;
}
virtual void k(void)
{
cout<<"Derived::k()"<<endl;
}
};
int main()
{
typedef void (*FUN)(void );
FUN func=NULL;
Derived d;
cout<<"member table address "<<(int*)(&d)<<endl;
cout<<"data member are follows:"<<endl;
cout<<*((int*)(&d)+1)<<endl;
cout<<*((int*)(&d)+2)<<endl;
cout<<*((int*)(&d)+4)<<endl;
cout<<*((int*)(&d)+5)<<endl;
cout<<"The two vptr address:"<<endl;
cout<<"the first vptr address "<<((int*)&d)<<endl;
func=(FUN)*((int*)*((int*)(&d)));
func();
func=(FUN)*((int*)*(int*)(&d)+1);
func();
func=(FUN)*((int*)*(int*)(&d)+2);
func();
func=(FUN)*((int*)*(int*)(&d)+3);
func();
cout<<endl;
cout<<"the second vptr address "<<(int*)&d+3<<endl;
func=(FUN)*((int*)*((int*)(&d)+3));
func();
func=(FUN)*((int*)*((int*)(&d)+3)+1);
func();
func=(FUN)*((int*)*((int*)(&d)+3)+2);
func();
func=(FUN)*((int*)*((int*)(&d)+3)+3);
func(); //运行时出错,非法访问,derived::k存放在Base2的虚函数表中
return 0;
}
运行结果:
member table address 0x22ff40
data member are follows:
3
4
1
2
The two vptr address:
the first vptr address 0x22ff40
Derived::f()
Base2::g()
Base2::h()
Derived::k()
the second vptr address 0x22ff4c
Derived::f()
Base1::g()
Base1::h()
Process returned -1073741819 (0xC0000005) execution time : 1.343 s
Press any key to continue.
根据运行结果可以得到如下结论:
(1) 派生类中的数据成员是按照对父类的继承顺序确定的。
(2) 虚函数指针在用户成员表中是按下图来存储的。
(3) 在派生类中新建的虚成员函数存放在所继承的第一个虚基类的虚函数表中。
程序1 程序2
vptr1 | vptr2 |
1 | 3 |
2 | 4 |
vptr2 | vptr1 |
3 | 1 |
4 | 2 |