你非要说指针本身就是一个对象,这也完全可以,不能说你错
下面这么说是可以的
- #include <iostream>
- class test_t {
- public:
- test_t(): n(0) {}
- private:
- int n;
- };
- int main() {
- int a = 0; // 创建了一个对象 a,类型是 int
- int *pa = &a; // 创建了一个对象 pa,类型是 int *
- int &ra = a; // 创建了一个对象 ra,类型是 int &
- test_t t; // 创建了一个对象 t,类型是 test_t
- test_t *pt = &t; // 创建了一个对象 pt,类型是 test_t *
- test_t &rt = t; // 创建了一个对象 rt, 类型是 test_t &
- return 0;
- }
复制代码
下面这个代码,你说调用函数 func 的时候,变量 c,需要额外空间吗?
如果你说需要,那么变量 a 和变量 b 也需要
如果你说变量 c 不需要,那么变量 a 和变量 b 也不需要
变量 a,b,c,这 3 个变量是一样的,都是函数的参数,都是局部变量
不一样的地方也有
变量 c 中存储的是数字 0,变量 c 占用 4 个字节的内存空间
变量 a 和变量 b 中存储的都是同一个数字,这个数字的值是 &x,这个 &x 就是一个地址,一个数字,一个比较大的数字
变量 a 和变量 b,占用 8 个字节
而变量 c 占用 4 个字节
注意,这是在我这边,在别的机器上,输出可能会不一样
- #include <iostream>
- void func(int &a, int *b, int c) {
- printf("a: %lu\n", sizeof(a));
- printf("b: %lu\n", sizeof(b));
- printf("c: %lu\n", sizeof(c));
- }
- int main() {
- int x = 0;
- func(x, &x, x);
- return 0;
- }
- /*
- a: 4
- b: 8
- c: 4
- */
复制代码
这里输出的 a 是 4,但是变量 a 不是占用 4 个字节,一定不是,一定是和变量 b 相同,b 是 8,a 一定是 8
之所以这里输出的 a 是 4,是因为这是在 C++ 层,因为变量 a 引用了 变量 x,这里的 sizeof(a),就是 sizeof(x),所以会得到 4,但是在汇编语言层,变量 a 占用 8 个字节,和变量 b 一样
- main:
- .LFB1738:
- pushq %rbp
- .seh_pushreg %rbp
- movq %rsp, %rbp
- .seh_setframe %rbp, 0
- subq $48, %rsp
- .seh_stackalloc 48
- .seh_endprologue
- call __main
- movl $0, -4(%rbp) # int x = 0;
- movl -4(%rbp), %ecx # c 使用 movl 指令,4 个字节
- leaq -4(%rbp), %rdx # b 使用 leaq 指令,8 个字节
- leaq -4(%rbp), %rax # a 使用 leaq 指令,8 个字节
- movl %ecx, %r8d
- movq %rax, %rcx
- call _Z4funcRiPii # call func
- movl $0, %eax
- addq $48, %rsp
- popq %rbp
- ret
复制代码
也就是说,所有的对象都不需要额外的空间,有这个对象本身的空间就够了
函数的参数就是个局部变量
具体每一个对象占用多少字节,用 sizeof 算一下就是了
但是,但是这个 sizeof 对引用无效,一个引用 使用 sizeof 算出来的是 引用的那个对象的大小,不是引用本身的大小,引用本身的大小和指针的大小是一样的