类大小计算
- 空类的大小为1字节
- 一个类中,虚函数本身、成员函数(包括静态与非静态)和静态数据成员都是不占用类对象的存储空间的
- 字节对齐的问题。与C语言一致
- 没有继承的时候,存在虚函数则需要加上虚指针vptr(+4个字节),如果有多个也只需要加上一个,因为只有一个虚指针。
- 虚基类指针:如果是虚继承,则子类的大小为:虚基类的大小 + 4个字节(用来存放指向虚基对象的指针)+子类新增成员的大小。
示例
#include <iostream>
using namespace std;
/**
* 8=4(x)+4 (vptr)
*/
class A {
public:
int x;
virtual void func() {
}
};
/**
* 16=4(x)+4 (vptr)+4(y)+4(vbPtr)
*/
class B : virtual public A {
public:
int y;
virtual void funcB() {
}
};
class B1 : virtual public A {
public:
int z;
virtual void funcB1() {
}
};
/**
* 16=4(x)+4 (vptr)+4(y)+4(B vbPtr)+4(A vbptr)+4(m)
*/
class C : virtual public B {
int m;
virtual void funcC() {
}
};
/**
* 16=4(x)+4 (vptr)+4(y)+4(B vbPtr)+4(A vbptr)+4(m)+4(z)+4(B1 vbptr)
*/
class D : public B, public B1 {
int n;
virtual void funcD() {
}
};
int main() {
A a;
B b;
C c;
D d;
cout << "sizeof(A)=" << sizeof(a) << endl;
cout << "sizeof(B)=" << sizeof(b) << endl;
cout << "sizeof(C)=" << sizeof(c) << endl;
cout << "sizeof(D)=" << sizeof(d) << endl;
return 0;
}
运行结果:
sizeof(A)=8
sizeof(B)=16
sizeof(C)=24
sizeof(D)=28
- sizeof(A):x的大小,存在虚函数则有vptr
- sizeof(B):x的大小,y的大小,存在虚函数则有vptr;虚继承,则还存在指向虚基类指针。
- sizeof(C):x的大小,y的大小,m的大小,存在虚函数则有vptr;虚继承,则还存在指向虚基类指针。而基类也是虚继承,基类中也有一个指向虚基类指针。
- sizeof(D)
静态成员变量
- 静态变量必须在外部定义和赋值
- a 不能在 main() 函数中定义
- b 不能在类的构造函数中定义
- 必须要定义静态变量,否则该变量没有内存空间(类中只是申明)
- 类本身可以直接调用静态变量
- 静态变量依旧符合public、private、protect特性
示例
- 声明
//C.h
class C {
private:
int a;
public:
static int b;
};
- 定义
//C.cpp
#include "C.h"
int C::b=10;
- 使用
int main() {
cout<<C::b<<endl;
C::b=100;
cout<<C::b<<endl;
return 0;
}
静态方法
- 静态方法可以被类直接调用,但是同静态变量一样符合public、private、protect特性
- 静态成员函数不可以调用类的非静态成员。因为静态成员函数不含this指针。
- 静态成员函数不可以同时声明为 virtual或后缀const 函数。因为virtual就是用来区分是哪个对象调用了他,与静态方法矛盾。而后缀const是用来修饰this指针的,静态变量中不包含this指针。