(1)单继承,无虚函数覆盖,无成员变量,无虚继承...1 (2继承无虚函数覆盖 有成员变量,无虚继承...3 (3)单继承有虚函数覆盖 有成员变量无虚继承... 5 (4)单继承 有虚函数覆盖有成员变量 虚继承...6 (5)多重继承 有成员变量虚函数覆盖 无虚继承...10 6)多重继承有成员变量 虚继承...14 (1)单继承,无虚函数覆盖,无成员变量,无虚继承
代码: #include <iostream> using namespace std;
class Base//只有三个虚函数 { public: virtualvoid f(){cout << "Base::f()" << endl;} virtualvoid g(){cout << "Base::g()" << endl;} virtualvoid h(){cout << "Base::h()" << endl;} };
class Derive: public Base { virtualvoid f1(){cout << "Derive::f1()" << endl;} virtualvoid g1(){cout << "Derive::g1()" << endl;} virtualvoid h1(){cout << "Derive::h1()" << endl;} };
typedef void(*fun)(void); int** pVtbl = NULL; fun pFun; int main() { Derived; pVtbl= (int**)(&d); cout<< "Derive._vptbl->" << endl; for(int i=0; (fun)pVtbl[0][i] !=NULL; i++) { pFun= (fun)pVtbl[0][i]; cout<< " ["<<i<< "]"; pFun(); } return0; } 运行结果:
补充: Sizeof(Base) = 4; sizeof(Derive) = 4; 因为其对象里面都只含有一个虚表指针;无其它成员变量;
(2)继承无虚函数覆盖 有成员变量,无虚继承
#include <iostream> using namespace std;
class Base { public: char bc; int bi; short bs;//这三个是在上面那个程序新加的依次是char int short; public: Base():bi(1),bc('b'),bs(1){} virtualvoid f(){cout << "Base::f()" << endl;} virtualvoid g(){cout << "Base::g()" << endl;} virtualvoid h(){cout << "Base::h()" << endl;} };
class Derive: public Base { public: int di; char dc; short ds;//这三个成员变量也是新加的,类型依次是int charshort不同于基类里的声明次序这个要注意,内存对齐就在这里体现出来; public: Derive():di(2),dc('d'),ds(2){} virtualvoid f1(){cout << "Derive::f1()" << endl;} virtualvoid g1(){cout << "Derive::g1()" << endl;} virtualvoid h1(){cout << "Derive::h1()" << endl;} }; Sizeof(Base) = 16;sizeof(Derive) = 24;
下面是Base的成员变量的布局:第一行表示地址假如从0x0000开始存储:
这就是自然对齐:内存地址/类型所占字节== 0;成员变量bc内存地址为0x0000; char所占字节为1;0x0000/1 ==0; 满足条件;下一个成员变量bi,不应该放在地址0x0001 0x0002 0x0003的,因为这三个内存地址/4 != 0;所以bi应该放在0x0004; 这样可以得到总共10个字节; 还要考虑内存对齐,所占的字节一定要是其中最大成员所占字节的整数倍; 所以Base所占内存为12字节; 而Derive的成员变量的布局,第一行表示地址,假如从0X0000开始存储:
运行结果:
源代码如上图所示作修改: 运行结果;
我们从表中可以看到下面几点, 1)覆盖的f()函数被放到了虚表中原来父类虚函数的位置。 2)没有被覆盖的函数依旧。 3)父类没有的虚函数在子类对象添加;
|