面试题答案
一键面试语法方面
- 相同点:
- 都可以用于间接访问数据。
- 不同点:
- 引用:定义时必须初始化,且一旦初始化后不能再引用其他变量,语法形式为
type& ref = var;
。 - 指针:定义时可不初始化,之后可以指向不同变量,语法形式为
type* ptr;
,使用时需解引用*ptr
访问指向的数据。
- 引用:定义时必须初始化,且一旦初始化后不能再引用其他变量,语法形式为
内存管理方面
- 相同点:
- 本身都不拥有所指向对象的内存所有权,内存的释放需开发者手动管理(在非智能指针情况下)。
- 不同点:
- 引用:不能为
nullptr
,所以不存在空引用,无需在使用前检查是否为空。 - 指针:可以为
nullptr
,使用前需检查是否为空指针,避免空指针解引用错误。
- 引用:不能为
安全性方面
- 相同点:
- 如果使用不当,都会导致程序错误和内存问题。
- 不同点:
- 引用:由于不能重新绑定且不存在空引用,相对指针在使用上更安全,可减少一些常见的编程错误。
- 指针:可随意改变指向,若指向非法内存区域,会导致未定义行为,安全性较低。
多态实现方面
- 相同点:
- 都能实现多态。通过基类指针或引用指向派生类对象,调用虚函数实现动态多态。
- 不同点:
- 引用:使用引用调用虚函数时,编译器通过对象的实际类型确定要调用的函数版本,语法简洁,无需解引用操作。
- 指针:使用指针调用虚函数时,需通过解引用指针访问对象来调用函数,语法上略显繁琐。
优先选择引用的场景
- 函数参数传递:当希望确保传递的对象始终有效且函数内部不改变其指向时,如
void func(const Type& obj)
,常用于传递大型对象以避免拷贝开销。例如在图形渲染库中,渲染函数接收图形对象的引用,确保对象有效且不被意外更改。 - 对象成员访问:在类的成员函数中访问其他成员对象时,若该成员对象在整个生命周期内都存在,使用引用更简洁安全。如
class A { B& b; A(B& _b) : b(_b) {} };
,常用于容器类与内部元素的关系。
优先选择指针的场景
- 动态内存分配:当需要在运行时决定对象的创建和销毁,且对象的生命周期需要灵活管理时,指针更合适。如
Type* ptr = new Type();
,在内存池管理等场景中,指针可方便地控制内存块的分配与释放。 - 可能为空的情况:当某个对象可能不存在时,使用指针可以表示空状态。如在链表节点查找中,若未找到目标节点,返回
nullptr
。