面试题答案
一键面试常引用作为函数参数的常见使用场景
- 提高效率且避免修改:当函数需要访问一个较大对象(如大数组、复杂结构体或类对象),但不希望对其进行修改时。例如:
#include <iostream>
#include <string>
void printString(const std::string& str) {
std::cout << str << std::endl;
}
int main() {
std::string largeStr = "This is a very large string";
printString(largeStr);
return 0;
}
在此例中,printString
函数仅需读取 std::string
对象,使用常引用避免了大字符串的拷贝,提高了效率,同时防止函数内部意外修改字符串。
- 传递临时对象:当需要传递一个临时对象给函数时,常引用可以绑定到临时对象,而普通引用不行。例如:
#include <iostream>
#include <string>
void processString(const std::string& str) {
std::cout << "Processing: " << str << std::endl;
}
std::string createString() {
return "Temporary string";
}
int main() {
processString(createString());
return 0;
}
这里 createString
返回一个临时 std::string
对象,常引用 const std::string&
能够接收这个临时对象。
相较于值传递和普通引用传递的优势
- 与值传递相比:
- 效率优势:值传递会对传递的对象进行拷贝,对于大对象来说,这会消耗大量时间和内存。而常引用传递不会拷贝对象,直接引用原对象,提高了效率。例如传递一个大的自定义结构体:
#include <iostream>
#include <vector>
struct BigStruct {
std::vector<int> data;
BigStruct() {
for (int i = 0; i < 1000000; ++i) {
data.push_back(i);
}
}
};
void funcByValue(BigStruct bs) {
// 函数体
}
void funcByConstRef(const BigStruct& bs) {
// 函数体
}
int main() {
BigStruct bs;
// 调用值传递函数会拷贝大结构体,开销大
funcByValue(bs);
// 调用常引用传递函数,无拷贝开销
funcByConstRef(bs);
return 0;
}
- **保护对象不被修改**:值传递函数内部可以修改拷贝对象,但常引用传递函数无法修改原对象,提供了对象的只读访问。
2. 与普通引用传递相比:
- 可绑定临时对象:普通引用不能绑定到临时对象,而常引用可以。如上面 processString(createString())
的例子,这使得常引用在函数调用时更加灵活。
- 语义清晰:常引用表明函数不会修改传入对象,普通引用则没有这种明确的语义,有助于代码的可读性和维护性。