返回值返回引用返回指针之间的区别

news2025/1/15 6:33:29
一、返回值

当函数返回一个值时,实际返回的是一个变量的拷贝。

优点:

  • 简单易用;
  • 安全,不会导致悬挂指针或悬挂引用;

缺点:

  • 当返回值是一个较大的对象时会产生拷贝开销,影响程序性能;
二、返回引用

当函数返回一个引用时,实际返回的是变量的别名。

优点:

  • 没有拷贝开销,不影响程序性能;
  • 可以用于返回对象本身,实现链式调用;

缺点:

  • 如果是局部变量的引用,会导致未定义行为(悬挂引用);
三、返回指针

当函数返回一个指针时,实际返回的是一个变量的地址。

优点:

  • 灵活性高
  • 可用于动态分配内存的返回;

缺点:

  • 不安全,可能产生内存泄漏;
  • 可能导致悬挂指针(返回了一个已经释放的内存);
四、总结

(1)适用场景

  • 返回值:适用于基本数据类型或小对象 ,不需要考虑性能问题。或需要使用临时对象的场景。
  • 返回引用:适用于较大的对象 ,需要考虑性能问题的场景。
  • 返回指针:适用于动态分配内存或指针灵活指向的场景。

(2)注意事项

  • 返回局部对象或局部变量时:局部变量和局部对象在使用后会被销毁 ,返回它们的引用会产生悬挂引用或悬挂指针。使用这些引用会产生未定义行为。
  • 内存管理: 对于函数内部手动分配的内存 ,在适当的时候需要进行销毁 ,以避免内存泄漏。不能返回指向已经被销毁的内存空间的指针。 如果函数返回一个指向动态分配内存的指针,在使用结束后必须手动销毁这段内存,以避免内存泄漏。
五、代码实例
#include <iostream>
#include <stdexcept>
#include <string>

using namespace std;

class Person
{
public:
    Person() {} // 默认构造
    Person(std::string name, int age, std::string sex) :name(name), age(age), sex(sex) {}   // 带参构造
    Person(const Person& p)
    {
        this->name = p.name;
        this->age = p.age;
        this->sex = p.sex;
        std::cout << std::endl << "对象拷贝" << std::endl;
    }
    friend std::ostream& operator<<(std::ostream& os, const Person& p);

private:
    std::string name;
    int age;
    std::string sex;
};

std::ostream& operator<<(std::ostream& os,const Person& p)
{
    os << "姓名: " << p.name << std::endl << "年龄: " << p.age << std::endl << "性别: " << p.sex << std::endl;
    return os;
}

// 返回值
int getInt()    
{
    int x = 10;
    return x;
}

// 返回引用
int& getIntReference(int &x)  
{
    return x;   // 返回 x 的引用
}

// 返回指针
int* getIntPointer(int* x)  
{
    if (x == nullptr) {
        throw std::invalid_argument("不能返回一个空指针");
    }
    return x;   // 返回 x 的地址
}

/* 
* 返回局部对象的引用
*/
Person& getLocalIntReference()
{
    // 不允许返回局部对象的引用,抛出异常
    throw std::runtime_error("不允许返回局部对象的引用");
}

/*
* 返回局部指针
*/
int* getLocalIntPointer()
{
    int arr[4] = { 1,2,3,4 };
    // 不允许返回局部指针,抛出异常
    throw std::runtime_error("不允许返回局部指针");
}

/*
* 返回动态分配的内存
*/
int* getMotionIntPointer()
{
    int* x = new int(10);
    if (x == nullptr) {
        throw std::runtime_error("不能返回一个空指针");
    }
    return x;
}

int main()
{
    try {
        std::cout << "返回值: " << getInt() << std::endl;
        
        int temp = getInt();
        std::cout << "返回引用: " << getIntReference(temp) << std::endl;
        
        int temp2 = getInt();
        std::cout << "返回指针: " << getIntPointer(&temp2) << std::endl;
        
        std::cout << "返回局部引用: " << getLocalIntReference() << std::endl;  // 会抛出异常
    } catch (const std::exception& e) {
        std::cerr << "捕获的异常: " << e.what() << std::endl;
    }

    try {
        std::cout << "返回局部指针: " << getLocalIntPointer() << std::endl;  // 会抛出异常
    } catch (const std::exception& e) {
        std::cerr << "捕获的异常: " << e.what() << std::endl;
    }

    try {
        int* ptr = getMotionIntPointer();
        std::cout << "返回动态内存: " << *ptr << std::endl;
        delete ptr;  // 确保释放动态分配的内存
    } catch (const std::exception& e) {
        std::cerr << "捕获的异常: " << e.what() << std::endl;
    }

    return 0;
}

六、运行结果

在这里插入图片描述

文章部分内容使用了ChatGPT,如有谬误,请各位大佬留言指正!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1819616.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

TcpClient 服务器、客户端连接

TcpClient 服务器 TcpListener 搭建tcp服务器的类&#xff0c;基于socket套接字通信的 1 创建服务器对象 TcpListener server new TcpListener(IPAddress.Parse("127.0.0.1"), 3000); 2 开启服务器 设置最大连接数 server.Start(1000); 3 接收客户端的链接,只能…

git如果将多次提交压缩成一次

将N个提交压缩到单个提交中有两种方式&#xff1a; git reset git reset的本意是版本回退&#xff0c;回退时可以选择保留commit提交。我们基于git reset的作用&#xff0c;结合新建分支&#xff0c;可以实现多次commit提交的合并。这个不需要vim编辑&#xff0c;很少有冲突。…

C语言| 编程获取数组的长度

用sizeof也可以获得整个数组在内存中所占的字节数。 总的字节数除以一个元素所占的字节数就是数组的总长度。 这样不管数组是增加还是减少元素&#xff0c;sizeof(a) /sizeof(a[0])都能自动求出数组的长度。 字符串中有一个strlen()函数可以求出字符数组中字符串的长度。 #inc…

Linux结业测试题,旨在检测ip网络配置,文件权限等基础

Linux期末结业考试 一、评分方式&#xff08;总分100分&#xff0c;理论40分在职教云考试&#xff09; 主要涉及的知识和技能点*分值权重*Linux的最小安装10%激活网络&#xff0c;并正确设置ip地址10%克隆1台机器&#xff0c;并正确设置ip地址10%SSH免密互信服务10%文件和目录…

硬件相关——硬盘分区

文章目录 系统分区什么是分区&我们为什么要用分区逻辑分区分区规则为什么主分区最多只能分4个&#xff1f;硬盘的结构扩展分区 格式化啥叫格式化为什么我们需要格式化索引呢&#xff1f; 系统分区 什么是分区&我们为什么要用分区 磁盘分区是指&#xff0c;使用分区编辑…

论文笔记:ATime-Aware Trajectory Embedding Model for Next-Location Recommendation

Knowledge and Information Systems, 2018 1 intro 1.1 背景 随着基于位置的社交网络&#xff08;LBSNs&#xff09;&#xff0c;如Foursquare和Facebook Places的日益流行&#xff0c;大量用户签到数据变得可用 这些大量签到数据的可用性带来了许多有用的应用&#xff0c;以…

Perl 语言入门学习

一、介绍 Perl 是一种高级的、动态的、解释型的通用编程语言&#xff0c;由Larry Wall于1987年开发。它是一种非常灵活和强大的语言&#xff0c;广泛用于文本处理、系统管理、网络编程、图形编程等领域。 Perl 语言的设计理念是“用一种简单的语法&#xff0c;去解决复杂的编…

基于注意力的MIL

多实例学习是监督学习的一种变体&#xff0c;其中单个类标签被分配给一袋实例。在本文中&#xff0c;作者将MIL问题描述为学习bag标签的伯努利分布&#xff0c;其中bag标签概率通过神经网络完全参数化。此外&#xff0c;提出了一种基于神经网络的置换不变聚合算子&#xff0c;该…

Spring Security——基于MyBatis

目录 项目总结 新建一个项目 pom.xml application.properties配置文件 User实体类 UserMapper映射接口 UserService访问数据库中的用户信息 WebSecurityConfig配置类 MyAuthenticationFailureHandler登录失败后 MyAuthenticationSuccessHandlerw登录成功后 WebSecur…

嘉之音真丝彩绘吸音画,把记忆与向往刻进艺术里

那一瞬间定格在记忆中 那一刹那感动到骨髓里 曾经 现在 将来 每一幅画&#xff0c;都是一个故事的开始&#xff0c;一段记忆的延续&#xff0c;它们承载着过去&#xff0c;映照着现在&#xff0c;启迪着未来。在艺术的世界里&#xff0c;每个人都能找到属于自己的那一幅画…

PyTorch -- Visdom 快速实践

安装&#xff1a;pip install visdom 注&#xff1a;如果安装后启动报错可能是 visdom 版本选择问题 启动&#xff1a;python -m visdom.server 之后打开出现的链接 http://localhost:8097Checking for scripts. Its Alive! INFO:root:Application Started INFO:root:Working…

pytorch神经网络训练(AlexNet)

导包 import osimport torchimport torch.nn as nnimport torch.optim as optimfrom torch.utils.data import Dataset, DataLoaderfrom PIL import Imagefrom torchvision import models, transforms 定义自定义图像数据集 class CustomImageDataset(Dataset): 定义一个自…

数据采集项目1-用户行为数据同步

环境准备 linux配置、克隆103和104、编写集群分发脚本、ssh无密码登录配置、jdk安装、数据模拟集群日志数据输出脚本、xcall脚本、安装hadoop、zk安装、kafka安装、flume安装、mysql安装、maxwell安装、datax安装、hive安装 用户行为数据同步-总的数据流程图 第一层flume 数据…

22 CRT工具安装流程

22 CRT工具安装流程 SecureCRT 9.5 说明书 SecureCRT 9.5是一款由VanDyke Software开发的终端仿真程序。它为Windows、Mac和Linux操作系统提供了强大的SSH&#xff08;Secure Shell&#xff09;客户端功能。SecureCRT 9.5提供了对Telnet、RLogin、Serial和X.509等协议的支持&…

没那么简单!浅析伦敦金与美元的关系

伦敦金价与美元的关系可以被比喻为跷跷板的两端&#xff0c;它们的价格走势往往呈现出此消彼长的关系&#xff1a;当美元表现强势的时候&#xff0c;伦敦金的价格可能承受到压力&#xff1b;相反&#xff0c;当美元疲软时&#xff0c;黄金往往会成为避险资产&#xff0c;令伦敦…

Flask快速入门(路由、CBV、请求和响应、session)

Flask快速入门&#xff08;路由、CBV、请求和响应、session&#xff09; 目录 Flask快速入门&#xff08;路由、CBV、请求和响应、session&#xff09;安装创建页面Debug模式快速使用Werkzeug介绍watchdog介绍快速体验 路由系统源码分析手动配置路由动态路由-转换器 Flask的CBV…

你还在手写数据库文档?推荐一款数据库文档生成工具screw

&#x1f604; 19年之后由于某些原因断更了三年&#xff0c;23年重新扬帆起航&#xff0c;推出更多优质博文&#xff0c;希望大家多多支持&#xff5e; &#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚忍不拔之志 &#x1f390; 个人CSND主页——Mi…

【调试笔记-20240612-Linux-在 QEMU 中配置 OpenWrt-23.05 支持访问 Windows 宿主机的共享目录】

调试笔记-系列文章目录 调试笔记-20240612-Linux-在 QEMU 中配置 OpenWrt-23.05 支持访问 Windows 宿主机的共享目录 文章目录 调试笔记-系列文章目录调试笔记-20240612-Linux-在 QEMU 中配置 OpenWrt-23.05 支持访问 Windows 宿主机的共享目录 前言一、调试环境操作系统&…

UEditor文件上传超出大小限制修改无效问题

网上说的方法&#xff0c;试过了&#xff0c;不生效 百度ueditor富文本编辑框怎么设置上传图片大小限制_umeditor 控制图片上传不得超过1m-CSDN博客 直接修改此处

[图解]《分析模式》漫谈02-第2章图的多重性错误

1 00:00:01,400 --> 00:00:02,790 今天&#xff0c;我们来看 2 00:00:04,440 --> 00:00:06,190 分析模式的第2章 3 00:00:06,960 --> 00:00:09,820 一个图上面的一些小问题 4 00:00:13,130 --> 00:00:15,320 第2章的图2.4 5 00:00:16,500 --> 00:00:22,190 …