1.基本特性

  • 指针 (Pointer):

    • 本质: 指针是一个变量

    • 存储内容: 它存储的是另一个对象的内存地址

    • 特性:

      • 可为空: 指针可以被设置为 nullptr (或 NULL),表示它不指向任何有效的对象。

      • 可被重新赋值: 指针可以“变心”,在它的生命周期内,它可以被修改为指向另一个不同的对象。

      • 有自己的内存: 作为一个变量,指针本身也占用内存空间(用来存储那个地址)。

      • 访问: 需要使用解引用操作符 * 来访问它所指向的对象。

  • 引用 (Reference):

    • 本质: 引用是一个别名 (Alias)

    • 存储内容: 它(概念上)不是一个变量,而是它所引用的那个对象的另一个名字

    • 特性:

      • 不能为空: 引用必须在声明时就被初始化,并且必须引用一个有效的、已存在的对象。它永远不能为 "null"。

      • 不可被重新赋值: 引用一旦被初始化,就永远“忠于”它最初引用的那个对象。你不能让这个引用再去“引用”另一个对象。

      • 没有自己的内存(概念上): 它只是原对象的一个标签,不占用额外的内存(尽管编译器在底层实现时通常会使用指针,但这只是实现细节,C++ 语言层面上它不占内存)。在底层实现中其实编译器就是把引用当成指针的解引用来操作的,只不过现在的编译器自己会有优化操作(比如消除多余的解引用、函数内联)。

      • 访问: 像操作原变量一样直接使用,不需要任何特殊操作符。

引用可以说是数据的别名,但本质上引用就是指针,是编译器给你的一块语法糖。你使用引用操作数据的时候就在底层就相当于用指针操作数据,只不过解引用等麻烦的活编译器底层帮你干了。引用会被c++编译器当做const指针来进行操作

2.区别

1.指针是一个变量,它保存了另一个变量的内存地址;引用是另一个变量的别名,与原变量共享内存地址。

2.指针(除指针常量)可以被重新赋值,指向不同的变量;引用在初始化后不能更改,始终指向同一个变量。

3.指针可以为 nullptr,表示不指向任何变量;引用必须绑定到一个变量,不能为 nullptr

4.使用指针需要对其进行解引用以获取或修改其指向的变量的值;引用可以直接使用,无需解引用。

3.如何使用

按照gemini的说法,如果指针和引用都可以使用的情况下,应优先使用引用,因为它用起来更方便,而且没有空值也更安全。一下两种情景推荐用引用:

  • 函数参数(输入/输出): 当你希望函数能修改调用者的变量,或者你想避免拷贝大对象(使用 const&)时。这是最常见的用途。

  • 操作符重载: 例如重载 []=<< 等操作符,使用引用能让语法更自然。

必须使用指针的时候使用指针,比如变量会为空或者需要指向不同的对象,使用指针的情景有:

  • "可空"语义: 当“没有对象”是一个有效状态时(例如,一个二叉树节点的子节点可能为空)。

  • 需要重新指向: 当你需要一个变量,它在不同时刻需要指向不同的对象时。

  • C 风格 API 和内存管理: 在处理动态分配的内存(new/delete)或与 C 库交互时。

  • 实现数据结构: 如链表、树等,节点需要包含指向其他节点的“链接”。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐