【C++温故】(1) sizeof

被打击到了,决定重新复习C++
从 sizeof 开始吧


基本数据类型

跟系统有关,以32位为例

类型boolcharshortunsigned intintlongfloatdouble
字节11244448

结构体

  • 涉及到字节对齐问题,总大小为最宽类型大小的整数倍
  • 空结构体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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值