编程C++ 开发者

描述 C++ 中指针和引用的工作原理。它们有什么区别,什么时候使用什么?

用 Hintsage AI 助手通过面试

答案。

问题历史:

指针是 C++ 中的基本工具之一,自语言出现以来就是内存管理和动态结构的基础,以及与低级系统库交互的基础。引用是在语言发布后(随着 C++ 的出现)添加的,以简化语法并提高代码的安全性。

问题:

内存使用的错误是 C++ 中最常见的问题之一,特别是在不正确使用指针时(悬空指针,内存泄漏)。有时新手不知道在什么情况下使用引用,什么情况下使用指针,或者错误地认为它们是完全可以互换的。

解决方案:

指针 (T*) 是一个存储对象地址的变量,可以是 nullptr,支持算术运算,允许动态分配和释放,并且可以改变指向的对象。

引用 (T&) 是对另一个现有对象的别名。引用在创建时必须初始化,不能是“空”的(引用空),不支持算术运算,但更方便且更安全(例如在传递给函数时)。

代码示例:

void increment_pointer(int* p) { if(p) ++(*p); } void increment_reference(int& r) { ++r; } int main() { int a = 5; increment_pointer(&a); increment_reference(a); }

关键特点:

  • 指针可以重新指向,但引用不可以
  • 引用必须立即与真实对象关联,指针可以是 nullptr
  • 在将值传递给函数时,引用通常更受欢迎;如果不能使用引用,则使用指针

具有陷阱的问题。

初始化后是否可以更改引用,以便它引用另一个对象?

不可以。C++ 中的引用是常量别名。初始化后,引用总是指向同一个对象,与可以重新指向的指针不同。

代码示例:

int a = 1; int b = 2; int& ref = a; // ref = b - 将 b 的值赋给 ref,但 ref 仍然指向 a

可以创建“空”引用或引用 nullptr 吗?

不可以,标准不允许引用不存在的对象。这会导致未定义的行为。

示例:

int* p = nullptr; // int& r = *p; - UB

int const ptr 和 const int ptr 有什么区别?**

int* const ptr 是一个指向 int 的常量指针(指针不能重新指向,但可以更改值)。const int* ptr 是一个指向常量 int 的指针(不能更改所指向的内容,但指针可以重新指向)。

代码示例:

int a = 1, b = 2; const int* ptr1 = &a; // *ptr1 不能更改,ptr1 = &b - 可以 int* const ptr2 = &a; // *ptr2 可以更改,ptr2 = &b - 不可以

常见错误和反模式

  • 使用引用指向临时值或已删除对象
  • 内存重新分配而不重新分配指针
  • “空”引用 - UB

生活中的例子

负面案例

年轻开发者使用指针传递参数,没有检查它们是否为 nullptr,在发生错误时导致崩溃。

优点:

  • 在错误发生之前正常工作

缺点:

  • 错误调用时不明显的崩溃
  • 难以查找错误

正面案例

经验丰富的开发者在保证传递时使用 int&,在可能为 nullptr 时使用 int*,并始终检查指针是否为 null。

优点:

  • 最小化内存错误
  • 函数语义明确

缺点:

  • 在处理动态内存时有时会遇到困难