• c++ 类的sizeof


    sizeof()是c++的运算符,返回变量或者类型占用的字节数。如sizeof(int) 为4,sizeof(char) 为1。

    那么类大小呢,如

    1 class A {
    2   char a;
    3   short b;
    4   int c;
    5 }

    那么sizeof(A)为多少,结果是8。char占用一字节,b占用2字节,int占用4字节,A为什么是8字节。这就涉及到c++字节对齐问题,如int类型的地址是4的倍数,short类型的地址是2的倍数。包含int的对象的指针也是4的倍数。所以如果A的指针为pa(pa应该是4的倍数),c的指针应该是pa+4,或者pa+8,或者...,取决于c之前声明的变量的大小。同理,a的指针为pa,b的指针为pa+2,中间填充了一个字节,c的指针为pa+4,最终A占用8字节。

    class B {
        char a,
        int c;
        short b;
    }

    sizeof(B)为什么,结果是12,原理同上,只不过c的指针为pa+4,b的指针为pa+8,而B的大小必须是类中最大的变量的倍数,所以sizeof(B) 为12

    class C {
        int c;
        short b;
        char a
    }

    sizeof(C)为8,原理同上。

    说完这个,再来看看函数会不会影响类的大小,如

    class D {
    public:
        D() {
        }
        ~D() {
        }
        void Show() {
        std::cout << "Show()" << std::endl;
        }
    }

    sizeof(D)结果为1,空类的大小也是1,说明non-virtual函数不占用类的大小,事实上,函数是编译在其他地方的,你可以用空指针来访问函数,如

    D *pd = NULL;
    pd->Show();

    前提是Show()里面没有访问类的变量,因为调用类成员函数时,会将类指针this传给成员函数,而我们传过去的是NULL,所以如果Show()里面调用类成员变量就会出错。

    non-virtual不占用类的大小,但是virtual函数需要占用,如把D的析构函数改成virtual的,即

    class D {
    public:
        D() {
        }
        virtual ~D() {
        }
        void Show() {
        std::cout << "Show()" << std::endl;
        }
    }

    sizeof(D)在32位机子上结果为4,在www.compileonline.com上结果为8。这涉及到虚函数原理——虚函数表

    一个类如果拥有虚函数,就会拥有一个虚函数表,但这个表并不保存在类中,类中保存的是一个指针,该指针指向需函数表的第一个位置,该位置是一个函数指针。

    class E {
    public:
        E() {
        }
        virtual ~E() {
        }
        virtual void Show() {
        std::cout << "Show()" << std::endl;
        }
    }

    sizeof(E)结果同样是4,因为虚函数表并没有保存在类中,类中保存的指向虚函数表的指针,当然,虚函数表变大了。

    可以通过虚函数表调用函数

    class F {
    public:
        F() {
        }
        void virtual f() {
            std::cout << "f()" << std::endl;
        }
        virtual void  g() {
            std::cout << "g()" <<std::endl;
        }
        void h() {
            std::cout << "h()" << std::endl;
        }
        virtual ~F()  {
        }
    };

    可以这么调用

    typedef void(* Fun)();
    Fun pfunf=(Fun)*(int *)*((int *)&f);
    Fun pfung=(Fun)*(int *)(*((int*)&f)+1)
    pfunf() // f()
    pfung() //g()

    虚函数表用来实现多态,每一对象保存这自己的虚函数表,调用虚函数时查看虚函数表,跟调用non-virtual函数是不同的。

  • 相关阅读:
    error:undefined reference to 'net_message_processor::net_message_processor()'
    android 网络检测
    eclipse 安装 ndk 组件
    eclipse下编译cocos2dx 3.0
    Cocos2dx3.0 TextField 输入中文的问题
    记录与骗子进行的一次交锋. 与技术无关
    关于继承的设计
    kubernetes1.5.2--部署dashboard服务
    kubernetes1.5.2--部署DNS服务
    kubernetes1.5.2集群部署过程--安全模式
  • 原文地址:https://www.cnblogs.com/clark-lee/p/3892684.html
Copyright © 2020-2023  润新知