C++引用指针大对比

C++
1.2k words

相似之处

间接访问对象:引用和指针都可以通过它们来间接访问和操作某个对象的值,而不是直接使用该对象的名字。

  • 引用:通过引用可以访问和操作所引用的对象。
  • 指针:通过指针的解引用(*)可以访问和操作指针指向的对象。

作为函数参数传递:两者都可以作为函数参数,允许函数操作调用者传递的对象,而不是对象的副本。

  • 引用示例:
    1
    2
    3
    void modify(int& ref) {
    ref = 20; // 直接修改传入的参数
    }
  • 指针示例:
    1
    2
    3
    void modify(int* ptr) {
    *ptr = 20; // 通过解引用修改传入的参数
    }

不同之处

语法上的区别

  • 引用

    • 语法上类似变量的别名,一旦定义,必须绑定到一个对象,且无法重新绑定。
    • 使用时不需要显式解引用,访问时与直接使用变量一样。
    1
    2
    3
    int x = 10;
    int& ref = x; // ref 是 x 的引用
    ref = 20; // 相当于修改 x,x 现在是 20
  • 指针

    • 是一种变量,存储的是另一个对象的地址。
    • 使用时需要通过解引用运算符*来访问指向的对象。
    • 可以指向nullptr或指向不同的对象,可以动态改变指向。
    1
    2
    3
    int x = 10;
    int* ptr = &x; // ptr 存储 x 的地址
    *ptr = 20; // 通过解引用修改 x,x 现在是 20

是否允许重新绑定

  • 引用:一旦绑定到一个对象,就不能再指向别的对象,即引用不能“重定向”。

    1
    2
    3
    4
    int a = 10;
    int b = 20;
    int& ref = a; // ref 绑定到 a
    ref = b; // 修改 a 的值为 20,ref 仍然引用 a,而不是重新绑定到 b
  • 指针:指针可以在运行时指向不同的对象,具有更大的灵活性。

    1
    2
    3
    4
    int a = 10;
    int b = 20;
    int* ptr = &a; // ptr 指向 a
    ptr = &b; // ptr 现在指向 b,可以修改它指向的对象

空值(Null)状态

  • 引用:引用必须绑定到一个有效的对象,不能为null。因此,引用总是指向某个有效的对象,使用起来比较安全。

  • 指针:指针可以指向nullptr,也可以指向一个未初始化的或无效的内存地址(悬空指针),这可能会导致运行时错误。

    1
    int* ptr = nullptr; // 指针可以为空

内存地址

  • 引用:引用本身并不占用额外的内存,它只是被引用对象的别名,没有独立的地址。

  • 指针:指针是一个变量,存储的是对象的内存地址,它本身占用一定的内存空间,并且可以通过取地址符&获取指针本身的地址。

    1
    2
    3
    int x = 10;
    int* ptr = &x;
    std::cout << &ptr; // 输出指针变量 ptr 自己的地址

初始化要求

  • 引用:引用在声明时必须初始化,且绑定后无法更改。

    1
    2
    int x = 10;
    int& ref = x; // 引用必须初始化
  • 指针:指针声明时可以不初始化,也可以在后面动态分配内存或改变指向的对象。

    1
    2
    int* ptr;      // 可以声明但不初始化
    ptr = new int(10); // 动态分配内存

与数组的关系

  • 引用:引用不能指向数组的元素之间,它只能引用整个数组或数组中的某个元素。

  • 指针:指针可以指向数组,并通过指针的偏移操作访问数组中的各个元素。

    1
    2
    3
    4
    int arr[] = {1, 2, 3};

    int* ptr = arr; // ptr 指向数组首元素
    std::cout << *(ptr + 1); // 访问第二个元素,输出 2

总结

特性 引用 指针
是否需要初始化 必须在声明时初始化 可以声明后再初始化
是否能为空 不能 可以为空 (nullptr)
是否可重新绑定 不能,绑定后不能更改 可以重新指向不同的对象
访问方式 直接使用 需要使用*解引用
是否可指向不同对象
内存占用 不占用额外内存 占用内存,存储对象地址
能否指向数组 不能用于遍历数组 可以用于数组遍历

何时使用引用 vs 指针?

  • 使用引用:当你希望变量始终引用某个对象,且不希望修改它所引用的对象时。通常用于函数参数传递,链式调用,返回值等,使用方便且安全。
  • 使用指针:当你需要指向不同的对象,或者需要动态管理内存时。指针灵活,但需要更加小心处理内存管理,防止出现悬空指针或内存泄漏等问题。
Comments