MST

星途 面试题库

面试题:C++ 常引用在类成员函数中的场景及优化

假设有一个复杂的 C++ 类,其中包含大量数据成员。在类的成员函数中,何时应该使用常引用作为参数,何时应该返回常引用?如果错误使用可能会导致什么问题,如何避免?请结合具体代码示例阐述。
23.5万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. 何时使用常引用作为参数
    • 当函数不需要修改传入的对象,且对象较大时,使用常引用作为参数可以避免对象的拷贝,提高效率。例如:
class BigData {
public:
    BigData() { /* 初始化大量数据 */ }
private:
    int data[10000];
};

class ComplexClass {
public:
    void processData(const BigData& bd) {
        // 在此处处理bd,但不会修改它
        // 例如读取bd中的数据进行计算
    }
};
  • 这里processData函数使用const BigData& bd作为参数,既可以高效地传递BigData对象,又能保证函数内部不会修改BigData对象。
  1. 何时返回常引用
    • 当返回的对象是类的内部数据成员,且不希望调用者通过返回值修改该内部数据成员时,返回常引用。例如:
class ComplexClass {
private:
    BigData internalData;
public:
    const BigData& getInternalData() const {
        return internalData;
    }
};
  • 这样,外部调用者只能读取getInternalData返回的BigData对象,而不能修改它。
  1. 错误使用可能导致的问题
    • 参数错误使用:如果函数不需要修改对象,但没有使用常引用作为参数,会进行不必要的对象拷贝,降低效率。例如:
class BigData {
public:
    BigData() { /* 初始化大量数据 */ }
private:
    int data[10000];
};

class ComplexClass {
public:
    void processData(BigData bd) {
        // 函数体未修改bd,但这里会进行拷贝
    }
};
  • 返回值错误使用:如果返回的常引用是一个局部对象,会导致悬空引用。例如:
const BigData& wrongReturn() {
    BigData localData;
    return localData;
}
  • wrongReturn函数返回后,localData被销毁,返回的引用指向已释放的内存,使用这个引用会导致未定义行为。
  1. 如何避免
    • 参数方面:仔细分析函数需求,如果函数不需要修改传入对象,一律使用常引用作为参数。
    • 返回值方面:确保返回的常引用指向的对象在函数返回后仍然有效。如果返回内部数据成员,要保证该成员的生命周期至少和调用者对返回值的使用周期一样长。例如上述getInternalData函数返回的是类的成员变量,其生命周期与类对象一致,不会出现悬空引用问题。