值返回与引用返回(c++)

目录

值返回

引用返回

二者的区别

生命周期

可以安全引用返回的情况

返回函数参数(传入的引用)

返回成员变量

返回动态分配的对象(但通常是返回指针)

禁止返回的类型

返回局部变量

返回临时对象

返回局部指针指向的对象

复制代码试一下

总结


在c++中函数可以返回值(by value)也可以返回引用(by reference)。

两者的根本区别在于返回的是对象的副本还是对象本身

值返回

返回对象的副本 ,调用者得到的是全新的独立对象

cpp 复制代码
// 值返回:返回类型不带&
string function1() {        // 返回string(值)
    string local = "hello would";
    return local;          // 返回local的副本
}

引用返回

返回对象的引用(别名) ,调用者得到的是已有对象的另一个名称,不创建新对象。

cpp 复制代码
// 引用返回:返回类型带&
string& function2() {       // 返回string&(引用)
    static string global = "world";
    return global;         // 返回global的引用(别名)
}

// const引用返回
const string& function3() { // 返回const string&(常量引用)
    static string global = "world";
    return global;         // 返回不能修改的引用
}

二者的区别

最主要的判断方式是其函数类型后是否跟着& 若其跟着&即为返回对象的引用 不创建新的对象

生命周期

值返回例子如下

cpp 复制代码
string version1(const string& s1, const string& s2)
{
	string temp;//创建局部变量temp(在栈上)
	temp = s2 + s1 + s2;//计算s2+s1+s2,赋值给temp
	return temp;//创建temp的副本(临时对象)作为返回值
}
//函数结束:temp被销毁(栈帧弹出)
//主函数中:用返回值初始化或赋值给result(调用拷贝构造函数或赋值运算符)

即可以得出version1返回的是值 并且在返回后temp被销毁 而其return的是temp的副本与temp本身的销毁无关 完全的独立

引用返回

version3 当函数结束后,temp就被销毁了,所以返回的引用将指向一个不再存在的对象,这会导致未定义行为。注意:不要返回局部变量的引用或指针

可以安全引用返回的情况

返回静态局部变量

cpp 复制代码
const string& getDefaultName() {
    static string defaultName = "Default";  // 静态变量 
    return defaultName;  // 安全:生命周期为整个程序不会随着函数结束而销毁
}

返回函数参数(传入的引用)

cpp 复制代码
​
string& appendStars(string& str) {
    str += "***";
    return str;  // 安全:str的生命周期由调用者管理
}

返回成员变量

cpp 复制代码
class Person {
private:
    string name;
public:
    const string& getName() const { return name; }  // 安全
    string& getName() { return name; }              // 安全(但有风险)
};

返回动态分配的对象(但通常是返回指针)

cpp 复制代码
string* createDynamicString() {
    return new string("Dynamic");  // 返回指针,调用者需delete
}

禁止返回的类型

返回局部变量

cpp 复制代码
const string& badFunction() {
    string local = "Local";  // 局部变量
    return local;  // 致命错误!返回后将指向无效内存
}

返回临时对象

cpp 复制代码
const string& badFunction2() {
    return string("Temporary");  // 临时对象,语句结束就销毁
}

返回局部指针指向的对象

cpp 复制代码
string& badFunction3() {
    string* ptr = new string("Dynamic");
    return *ptr;  // 危险:内存泄漏风险,调用者不知道需要delete
}

总结 注意:不要返回局部变量的引用或指针

复制代码试一下

cpp 复制代码
//strquote.cpp -- different designs
#include<iostream>
#include<string>
using namespace std;
string version1(const string& s1, const string& s2);
const string& version2(string& s1, const string& s2);	//has side effect
const string& version3(string& s1, const string& s2);	//bad design
 
int main()
{
	string input;
	string copy;
	string result;
 
	cout << "Enter a string: ";
	getline(cin, input);
	copy = input;
	cout << "Your string as entered: " << input << endl;
	result = version1(input, "***");
	cout << "Your string enhanced: " << result << endl;
	cout << "Your original string: " << input << endl;
 
	result = version2(input, "###");
	cout << "Your string enhanced: " << result << endl;
	cout << "Your original string: " << input << endl;
 
	cout << "Resetting original string.\n";
	input = copy;
	result = version3(input, "@@@");
	cout << "Your string enhanced: " << result << endl;
	cout << "Your original string: " << input << endl;
	return 0;
}
 
string version1(const string& s1, const string& s2)
{
	string temp;
	temp = s2 + s1 + s2;
	return temp;
}
 
const string& version2(string& s1, const string& s2)	//has side effect
{
	s1 = s2 + s1 + s2;
//safe to return reference passed to function
	return s1;
}
 
const string& version3(string& s1, const string& s2)	//bad design
{
	string temp;
	temp = s2 + s1 + s2;
//unsafe to return reference to local variable
	return temp;
}

此代码可以帮助你观察与理解值返回与引用返回的区别

总结

场景 值返回 引用返回
返回计算结果 ✅ 推荐 ⚠️ 需确保对象有效
返回局部创建的对象 ✅ 安全 ❌ 绝对禁止
返回输入参数 ⚠️ 可能低效 ✅ 高效
返回静态数据 ⚠️ 可能拷贝 ✅ 高效
链式调用 ❌ 不能链式 ✅ 支持链式
函数修改参数 ❌ 不能修改 ✅ 可以修改
多线程安全 ✅ 线程安全 ⚠️ 需同步访问
相关推荐
爱吃牛肉的大老虎16 分钟前
Rust对象之结构体,枚举,特性
开发语言·后端·rust
bbq粉刷匠29 分钟前
HashMap 底层原理深度拆解(二):putVal 完整链路解析(懒加载 · 链表遍历 · 尾插法)
java·开发语言·哈希算法
迷途之人不知返1 小时前
lambda表达式
c++
@三十一Y1 小时前
C++:红黑树的实现
开发语言·c++
_wyt0011 小时前
拓扑排序:有向无环图的排队艺术
c++·拓扑排序·队列
皓月斯语1 小时前
B2118 验证子串
c++·题解
乐观勇敢坚强的老彭2 小时前
C++信奥:开关门、开关灯问题
开发语言·c++·算法
冻柠檬飞冰走茶2 小时前
PTA基础编程题目集 7-31 字符串循环左移(C语言实现)
c语言·开发语言·数据结构·算法
a1117762 小时前
中文优先的企业 RAG 知识库 开源项目
开发语言·开源·kotlin
2301_777998343 小时前
C/C++:预处理详解
c语言·c++