Chinaunix首页 | 论坛 | 博客
  • 博客访问: 103369
  • 博文数量: 34
  • 博客积分: 30
  • 博客等级: 民兵
  • 技术积分: 217
  • 用 户 组: 普通用户
  • 注册时间: 2013-01-10 23:36
文章分类
文章存档

2013年(34)

我的朋友

分类: C/C++

2013-05-02 15:29:01

空类的sizeof为1,单一继承的空类空间也为1,多重继承的空类空间还为1.

    class Base
    {
    public:
Base();
~Base();
    };

  sizeof(Base)=1;
静态变量存储在全局数据区,而sizeof计算栈中分配的大小,是不会计算在内的
普通成员函数与sizeof无关
虚函数由于要维护在虚函数表,所以要占据一个指针大小,也就是4字节

class Base
{
public:
Base();               
virtual ~Base();         //每个实例都有虚函数表
void set_num(int num)    //普通成员函数,为各实例公有,不归入sizeof统计
{
a=num;
}
private:
     int  a;                  //占4字节
     char *p;                 //4字节指针
};

class Derive:public Base
{
public:
Derive():Base(){};    
~Derive(){};
private:
static int st;         //非实例独占
     int  d;                     //占4字节
     char *p;                    //4字节指针
};

int main()
{
cout< cout< return 0;
}
结果是

12

20

分析:Base类里的int  a;char *p;占8个字节。而虚析构函数virtual ~Base();的指针占4子字节。其他成员函数不归入sizeof统计。

          Derive类首先要具有Base类的部分,也就是占12字节。int  d;char *p;占8字节static int st;不归入sizeof统计所以一共是20字节。

有编译器额外加入的成员变量的大小,用来支持语言的某些特性(如:指向虚函数的指针、虚继承、多重继承

#include

class a {};
class b{};
class c:public a{
virtual void fun()=0;
};
class d:public b,public c{};
int main()
{
cout<<"sizeof(a)"<
cout<<"sizeof(b)"<
cout<<"sizeof(c)"<
cout<<"sizeof(d)"<
return 0;}

程序执行的输出结果为:

sizeof(a) =1

sizeof(b)=1

sizeof(c)=4

sizeof(d)=8


虚函数
#include
using namespace std;
class A
{
public:
    virtual void aa(){}
private:
    char k[3];
};
class B: public A
{
public:
    virtual void bb(){}
};
int main()
{
    cout<<"A's size is "<     cout<<"B's size is "<     return 0;
}
VS和gcc下执行结果:

A's size is 8

B's size is 8

 

  • 虚继承
  • [cpp]
    #include
    using namespace std;
    class A
    {
    public:
        virtual void aa(){}
    private:
        char k[3];
    };
    class B: virtual public A
    {
    public:
        virtual void bb(){}
    };
    int main()
    {
        cout<<"A's size is "<
        cout<<"B's size is "<
        return 0;
    }
    vs和gcc下
    执行结果:

    A's size is 8
            B's size is 12
     
    说明:类B里包含,继承的char k[3],继承的虚函数,类B的虚函数表里有A::aa(),因为是虚继承,还有一个指向父类的指针,该指针为指向虚基类的指针(Pointer to virtual base class)。考虑内存对齐,总大小为12。

  • 多重继承
  • #include
    using namespace std;
    class A
    {
        char k[3];
        public:
        virtual void aa(){};
    };
    class B
    {
        char q[3];
        public:
        virtual void bb();
    };
    class C: public A,public B
    {
        char j[3];
        public:
        virtual void cc(){};
    };
    int main()
    {
        cout<<"sizeof(A):"<     cout<<"sizeof(B):"<     cout<<"sizeof(C):"<     return 0;
    }
    sizeof(A):8
    sizeof(B):8
    sizeof(C):20

    像这种继承方式,在类C中会维护两个虚函数指针,第一个指向第一个基类的虚函数表(并且带上在类C中定义的虚函数),第二个指针指向第二个基类(B)的虚函数表...其他的类似。


    综合例子:


    #include
    using namespace std;
    class A
    {
    char k[3];
    public:
    virtual void f(){};
    };
    class B : public virtual A
    {
        char i[3];
    public:
    virtual void f1(){};
    };
    class C: public virtual A{
    //virtual void f(){};
    char j[3];
    public:
    virtual void t(){};
    };
    class D: public B,public C
    {
        char g[3];
        public:
        virtual void s();
    };
    int main()
    {
        cout<    cout<    cout<    cout<   return 0;
    }

    最后得到的结果是  8 16 16 28

    最主要的是sizeof(D): 4个char数组,对齐后是16,又是多重继承,那么有两个虚函数表的指针,又需要维护一分A类的指针,那么是16+4*2+4=28...采用虚继承,目的就是为了解决二义性和减小内存开销,所以在D中只维护一份A的指针便可。


    #include
    using namespace std;
    class A
    {
    char k[3];
    public:
    virtual void f(){};
    };
    class B : public virtual A
    {
        char i[3];
    public:
    virtual void f1(){};
    };
    class C: public virtual A{
    //virtual void f(){};
    char j[3];
    public:
    virtual void t(){};
    };
    class D: public B,public C
    {
        char g[3];
        public:
        virtual void s();
    };
    int main()
    {
        cout<    cout<    cout<    cout<   return 0;
    }

    最后得到的结果是  8 16 16 28

    最主要的是sizeof(D): 4个char数组,对齐后是16,又是多重继承,那么有两个虚函数表的指针,又需要维护一分A类的指针,那么是16+4*2+4=28...采用虚继承,目的就是为了解决二义性和减小内存开销,所以在D中只维护一份A的指针便可。




     

    阅读(1729) | 评论(0) | 转发(0) |
    0

    上一篇:0-1背包问题

    下一篇:平衡二叉树

    给主人留下些什么吧!~~