被打击到了,决定重新复习C++
从 sizeof 开始吧
基本数据类型
跟系统有关,以32位为例
类型 | bool | char | short | unsigned int | int | long | float | double |
---|---|---|---|---|---|---|---|---|
字节 | 1 | 1 | 2 | 4 | 4 | 4 | 4 | 8 |
结构体
- 涉及到字节对齐问题,总大小为最宽类型大小的整数倍
- 空结构体sizeof值为1
struct st1
{
char a;
int b;
};
sizeof(st1); // 为8,char 后会补3个字节
struct st2
{
};
sizeof(st2); // 为1
联合体
联合体共享一段内存,总大小为最宽成员的大小
union un1
{
int a;
float b;
double c;
};
sizeof(un1); // 为8
指针
对于32位机器,任何类型的指针占用 4
数组
- sizeof大小为数组所占内存字节数
- 字符数组表示字符串时,要计算’/0’
- 数组做形参时,相当于一个指针的值
char ch1[] = {'a', 'b', 'c'}; // sizeof(ch1) == 3
char ch2[] = "abc"; // sizeof(ch2) == 4
char ch3[5]; // sizeof(ch3) == 5
void func(char a[], char b[2])
{
sizeof(a); // 4 (指针)
sizeof(b); // 4 (指针)
}
枚举
enum默认会转为int,一个enum无论包含多少项都只占一个int(就理解为1个int声明)
enum em1
{
DAY1,
DAY2,
DAY3,
DAY4,
DAY5
};
sizeof(em1); // 为 4 (一个int的大小)
struct st1
{
enum em2 {WEEK1, WEEK2, WEEK3};
};
sizeof(st1); // 为 1,因为这里没有定义任何变量,结构体为空
struct st2
{
em1 myEm;
};
sizeof(st2); // 为 4,定义了一个枚举变量
函数
- 仅可计算有返回值的函数
- 有参数的函数必须使用实参(就是假装运行这个函数得到一个值)
- sizeof为函数返回类型的大小
int func1(int a, int b)
{
return 0;
}
int func2()
{
return 0;
}
void func3()
{
return;
}
cout << "sizeof(func1)="<<sizeof(func1(2, 3))<<endl; // 为 4
cout << "sizeof(func1)="<<sizeof(func1(int, int))<<endl; // 编译错误,输入必须为实参
cout << "sizeof(func2)="<<sizeof(func2())<<endl; // 为 4
cout << "sizeof(func3)="<<sizeof(func3())<<endl; // 编译错误,因为返回为void
类
- 类内 static 不计(因为是共享的)
- 类内 普通函数不计
- 类内 有(多个)虚函数时,会有一个指向虚函数的指针,32位系统中占 4 字节
- 类也会有字节对齐,总大小为最宽类型的整数倍
- 子类需要加上父类大小
- 父类里面有虚函数,子类里面虚函数不再计(公用一个虚函数表)
- 虚继承还需加上一个指向基类的指针
空类
class base1
{};
sizeof(base1); // 为 1
class base2
{
public:
base();
~base();
};
sizeof(base2); // 为 1
class base3
{
public:
base();
~base();
void func1(){..} // 普通函数为各实例共有
static int b; // static 不计
};
sizeof(base3); // 为 1
字节对齐
class base4
{
public:
base4();
~base4();
private:
int a;
char b;
};
sizeof(base4); // 为 8
虚函数
class base5
{
public:
base5();
~base5();
virtual void funcA();
virtual void funcB();
private:
int a;
char b;
};
sizeof(base5); // 为 12
普通继承
class base6:pubilc base5
{
public:
base6();
~base6();
private:
int a;
};
sizeof(base6); // 为 12+4=16
class base7:pubilc base5
{
public:
base7();
~base7();
virtual void funcC();
private:
int a;
};
sizeof(base7); // 为 12+4=16,虚函数不再单独计算
虚拟继承
class base8:virtual pubilc base5
{
public:
base8();
~base8();
private:
int a;
};
sizeof(base8); // 为 12+4+4=20
一个更复杂的例子:菱形继承
class top
{
public:
top();
virtual ~top();
};
class left:virtual public top
{
public:
left();
};
class right:virtual public top
{
public:
right();
};
class bottom:public left, public right
{
public:
bottom();
}
sizeof(top); // 4
sizeof(left); // 8
sizeof(right); // 8
sizeof(bottom); // 4+4+4+0=12,注意不要重复计算 top 的size