博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
单继承,多继承,虚拟继承,sizeof大小
阅读量:6048 次
发布时间:2019-06-20

本文共 2764 字,大约阅读时间需要 9 分钟。

1. 题目   

#include
using namespace std; class S {}; class A:S {
virtual void fun() {
; } }; class B:A {
virtual void fun() {
; } }; class C:B {
virtual void fun() {
; } }; class M {
virtual void fun() {} }; class N {
virtual void fun() {} }; class P:M,N {
virtual void fun() {} }; //------------------------------ class T_S {}; class T_A:virtual T_S {
virtual void fun() {
; } }; class T_B:virtual T_A {
virtual void fun() {
; } }; class T_C:virtual T_B {
virtual void fun() {
; } }; class T_M {
virtual void fun() {} }; class T_N {
virtual void fun() {} }; class T_P:virtual T_M,T_N {
virtual void fun() {} }; int main() {
// ---------------------------- // 单继承 cout << sizeof(S) << endl; // 1, 空类 cout << sizeof(A) << endl; // 4, 一个虚函数指针 cout << sizeof(B) << endl; // 4, 一个虚函数指针 cout << sizeof(C) << endl; // 4, 一个虚函数指针 //------------------------------ // 多继承 cout << sizeof(M) << endl; // 4, 一个虚函数指针 cout << sizeof(N) << endl; // 4, 一个虚函数指针 cout << sizeof(P) << endl; // 8, 两个虚函数指针,多继承 //------------------------------ // 单继承 cout << sizeof(T_S) << endl; // 1, 空类 cout << sizeof(T_A) << endl; // 4, 一个虚函数指针 cout << sizeof(T_B) << endl; // 4, 一个虚函数指针 cout << sizeof(T_C) << endl; // 4, 一个虚函数指针 //------------------------------ // 多继承 cout << sizeof(T_M) << endl; // 4, 一个虚函数指针 cout << sizeof(T_N) << endl; // 4, 一个虚函数指针 cout << sizeof(T_P) << endl; // 8, 两个虚函数指针,多继承 //------------------------------ system("PAUSE"); return 0; }

2. 分析

    S是空类,大小默认是1。

    A继承自S,S为空,A本身有虚函数,因此A需要有一个虚指针,因此A大小为4。
    B继承自A,A大小为4有一个虚指针,B沿用A的虚指针,因此B大小为4。
    C继承自B,B大小为有一个虚指针(实际上是沿用了A的虚指针),因此C沿用B的虚指针,因此C大小为4。
    实际上,一个类对应一个虚表,上面的虚指针沿用是针对类来说的,上面A,B,C三个类分别有一个虚指针,当然B和C的都是继承来的。
    对于虚拟继承,即TS,TA,TB,TC并没有改变虚指针的问题,也没有像一下bolg文章里面说的,虚继承相当与增加虚表指针和父类的所有东西。
    值得注意的是:A类如果有虚指针,其子类无论有没有虚函数,都会继承上面的虚指针,而且子类即使有虚函数也不会再去增加一个自己的虚指针,每个类最多有一个虚指针,对应最多有一个虚表。
    M有一个虚指针,N有一个虚指针,P继承了M和N,有两个虚指针,因此P的大小为8。

    PS:以上针对32机器,指针长度为4字节。

3. 补充一个和前面的题目有微小区别   

#include 
using namespace std; class S {}; class A:public S {
public: virtual void func() { cout << "A" << endl; } }; class B:public A {
public: virtual void func() { cout << "B" << endl; } }; class C:public A {
public: void func() { cout << "C" << endl; } }; class D:public C {
}; int main() {
A* pa = new A; A* pb = new B; A* pc = new C; pa->func(); // A pb->func(); // B pc->func(); // C cout << sizeof(S) << endl; // 1 cout << sizeof(A) << endl; // 4 cout << sizeof(B) << endl; // 4 cout << sizeof(C) << endl; // 4 cout << sizeof(D) << endl; // 4 system("PAUSE"); return 0; }

    主要区别就是C类的func函数不是虚函数,那么pc->func()输出仍旧是C,因为动态编联的实现只要求基类为虚函数即可,因为基类有虚函数,那么基类必然有虚指针,子类也就必然有虚指针了。所以动态编联不需要额外定义子类为虚函数。

转载地址:http://bpxex.baihongyu.com/

你可能感兴趣的文章
pxe实现系统的自动化安装
查看>>
Redis高可用技术解决方案总结
查看>>
Scale Out Owncloud 高可用(2)
查看>>
何为敏捷
查看>>
HA集群之四:Corosync+Pacemaker+DRBD实现HA Mysql
查看>>
服务器定义
查看>>
我的友情链接
查看>>
分布式系统的面试题15
查看>>
个人代码库の创建快捷方式
查看>>
由strcat函数引发的C语言中数组和指针问题的思考
查看>>
无锁编程
查看>>
如何在loadrunner中做关联
查看>>
二叉树的六种遍历方法汇总(转)
查看>>
用wxpython制作可以用于 特征筛选gui程序
查看>>
【转载】 [你必须知道的.NET]目录导航
查看>>
数据存储小例
查看>>
C++中构造函数详解
查看>>
电商网站中添加商品到购物车功能模块2017.12.8
查看>>
android 模拟器 hardWare 属性说明
查看>>
六款值得推荐的android(安卓)开源框架简介
查看>>