MST
星途 面试题库

面试题:C++ 中引用与指针在函数参数传递场景下的选择差异

在 C++ 中,函数参数传递时,有时使用引用,有时使用指针。请举例说明在哪些具体场景下更适合使用引用传递参数,哪些场景下更适合使用指针传递参数,并阐述原因。
36.2万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

适合使用引用传递参数的场景及原因

  1. 避免对象拷贝
    • 场景:当函数参数为较大的自定义对象时,例如一个包含大量成员变量的类对象。
    • 示例
class BigObject {
public:
    int data[1000];
};

void functionWithReference(const BigObject& obj) {
    // 对obj进行操作,不会发生对象拷贝
}
  • 原因:使用引用传递参数,不会产生对象的副本,直接操作传入的对象,提高了效率,减少了内存开销。
  1. 返回函数内部修改的对象
    • 场景:希望在函数内部修改传入的对象,并将修改后的对象返回给调用者。
    • 示例
class Counter {
public:
    int count;
};

Counter& increment(Counter& counter) {
    counter.count++;
    return counter;
}
  • 原因:通过引用返回对象,可以直接返回对传入对象的修改,而不是返回对象的副本,提高效率,并且可以方便地进行链式调用。
  1. 简化代码表达
    • 场景:对于简单的基本类型或小型对象,并且不希望函数内部修改传入的值。
    • 示例
void printValue(const int& value) {
    std::cout << value << std::endl;
}
  • 原因:引用语法比指针更简洁,并且在这种情况下同样可以避免不必要的拷贝,使代码更易读。

适合使用指针传递参数的场景及原因

  1. 参数可能为空指针
    • 场景:函数需要处理参数可能为空的情况,例如在链表操作中,插入节点的函数,当链表头指针可能为空时。
    • 示例
struct ListNode {
    int val;
    ListNode* next;
    ListNode(int x) : val(x), next(NULL) {}
};

void insertNode(ListNode*& head, int val) {
    ListNode* newNode = new ListNode(val);
    if (head == NULL) {
        head = newNode;
    } else {
        ListNode* current = head;
        while (current->next != NULL) {
            current = current->next;
        }
        current->next = newNode;
    }
}
  • 原因:指针可以为空,这使得函数能够处理一些特殊情况,如空链表的初始化。而引用不能为空,若使用引用在这种情况下会导致程序错误。
  1. 动态内存管理
    • 场景:函数需要对传入的对象进行动态内存分配或释放操作。
    • 示例
void deleteObject(int* ptr) {
    delete ptr;
}
  • 原因:指针直接指向动态分配的内存,通过指针可以方便地对这块内存进行释放等操作。而引用在对象生命周期结束时自动析构,不适合用于直接控制动态内存的释放等操作。
  1. 数组参数
    • 场景:当函数参数为数组时,数组名本质上是一个指针。
    • 示例
void printArray(int* arr, int size) {
    for (int i = 0; i < size; i++) {
        std::cout << arr[i] << " ";
    }
    std::cout << std::endl;
}
  • 原因:数组作为参数传递时,传递的是数组首元素的地址,即指针。使用指针操作数组更加自然和直接,能方便地进行数组元素的访问和遍历。