先看代码分析:
#include <iostream>
using namespace std;
class base1
{
public:
virtual void f()
{
cout << "base1::f()\n";
}
virtual void g()
{
cout << "base1::g()\n";
}
};
class base2
{
public:
virtual void h()
{
cout << "base2::h()\n";
}
virtual void i()
{
cout << "base2::i()\n";
}
};
class derived:public base1,public base2
{
virtual void f()
{
cout << "derived::f()\n";
}
virtual void i()
{
cout << "derived::i()\n";
}
virtual void x()
{
cout << "derived::x()\n";
}
};
typedef void(*Func)();
void main()
{
cout << "sizeof(base1):" << sizeof(base1) << endl;
cout << "sizeof(base2):" << sizeof(base1) << endl;
cout << "sizeof(derived):" << sizeof(derived) << endl;
cout << "----------------------------\n";
derived d;
base1 &b1 = d;
base2 &b2 = d;
b1.f();
b1.g();
b2.h();
b2.i();
cout << "------------------------------------\n";
long *vptr_addr1 = (long *)&d;
long *vptr1 = (long *)(*vptr_addr1);
Func f1 = (Func)vptr1[0];
f1();
long *vptr_addr2 = vptr_addr1 + 1;
long *vptr2 = (long *)(*vptr_addr2);
Func x = (Func)vptr2[0];
x();
Func y = (Func)vptr2[1];
y();
system("pause");
}
结果: 总结: 从运行结果可以看出子类是8个字节,所以它有两个虚函数表指针。 一个对象,如果它的类有多个基类则有多个虚函数表指针(注意是两个虚函数表指针,而不是两个虚函数表) 在多继承中,对应各个基类的vptr按继承顺序依次放置在类的内存空间中,且子类与第一个基类共用一个vptr(第二个基类有自己的vptr) 从图可以看出: (1)子类对象有两个虚函数表指针vptr1、vptr2; (2)同时子类也有两个虚函数表,因为它继承自两个基类。 (3)子类和第一个基类共用一个vptr(因为指向一个虚函数表,所以也可以说子类和第一个基类共用一个虚函数表vtbl)因为从图可以看出vtbl1有5个虚函数,其余三个是子类自己的。
|