值返回与引用返回(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;
}

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

总结

场景 值返回 引用返回
返回计算结果 ✅ 推荐 ⚠️ 需确保对象有效
返回局部创建的对象 ✅ 安全 ❌ 绝对禁止
返回输入参数 ⚠️ 可能低效 ✅ 高效
返回静态数据 ⚠️ 可能拷贝 ✅ 高效
链式调用 ❌ 不能链式 ✅ 支持链式
函数修改参数 ❌ 不能修改 ✅ 可以修改
多线程安全 ✅ 线程安全 ⚠️ 需同步访问
相关推荐
惊讶的猫3 小时前
工具选对之后还不够:商城 Agent 的参数与权限治理
开发语言·python
cmpxr_3 小时前
【MicroPython】如何刷新ESP8266的固件
开发语言·micropython
搭贝4 小时前
上厕所的时间搭好一套系统:AI自动生成实测
开发语言·人工智能·低代码·ai·php·搭贝
智感子4 小时前
智能称重·数据上云:从仪表读数到可追溯的计量凭证
开发语言·php
\光辉岁月/4 小时前
7.javase-面向对象
java·开发语言
weixin_531094694 小时前
heap_4内存管理
java·开发语言·算法
余额瞒着我当琳4 小时前
红黑树的实现--红黑树的概念、规则、效率、结构、旋转、查找、验证
数据结构·c++·算法
疯狂的维修4 小时前
关于用C#写电机起保停控制
开发语言·c#
青少儿编程课堂4 小时前
AC自动机多模式串匹配精讲:校园关键词巡检实战解析
c++·python·算法·bfs·信息学竞赛
longlongzihan5 小时前
LeetCode 5. 最长回文子串:从暴力匹配到中心扩展的思维演进
c++·算法·leetcode