2013年(34)
分类: C/C++
2013-05-02 15:29:01
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<
}
结果是
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 "<
}
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):"<
}
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<
}
最后得到的结果是 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<
}
最后得到的结果是 8 16 16 28
最主要的是sizeof(D): 4个char数组,对齐后是16,又是多重继承,那么有两个虚函数表的指针,又需要维护一分A类的指针,那么是16+4*2+4=28...采用虚继承,目的就是为了解决二义性和减小内存开销,所以在D中只维护一份A的指针便可。