问题历史:
指针是 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); }
关键特点:
初始化后是否可以更改引用,以便它引用另一个对象?
不可以。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 - 不可以
年轻开发者使用指针传递参数,没有检查它们是否为 nullptr,在发生错误时导致崩溃。
优点:
缺点:
经验丰富的开发者在保证传递时使用 int&,在可能为 nullptr 时使用 int*,并始终检查指针是否为 null。
优点:
缺点: