【C++】返回值是类名和返回值是引用的区别

2023-11-10

返回非引用类型:

函数的返回值用于初始化在调用函数时创建的临时对象(temporary object),如果返回类型不是引用,在调用函数的地方会将函数返回值复制给临时对象。
在求解表达式的时候,如果需要一个地方存储其运算结果,编译器会创建一个没命名的对象,这就是临时对象。C++程序员通常用temporary这个术语来代替temporary object。
用函数返回值初始化临时对象与用实参初始化形参的方法是一样的。
当函数返回非引用类型时,其返回值既可以是局部对象,也可以是求解表达式的结果。

返回引用类型:

当函数返回引用类型时,没有复制返回值,相反,返回的是对象本身。
千万不要返回局部对象的引用!千万不要返回指向局部对象的指针!
当函数执行完毕时,将释放分配给局部对象的存储空间。此时对局部对象的引用就会指向不确定的内存!返回指向局部对象的指针也是一样的,当函数结束时,局部对象被释放,返回的指针就变成了不再存在的对象的悬垂指针。

返回引用时,要求在函数的参数中,包含有以引用方式或指针方式存在的,需要被返回的参数。

如果返回对象,最后多执行一次拷贝构造函数,如果返回引用,直接返回现存对象

#include <iostream>
using namespace std;

class Timer
{
public:
    Timer();
    Timer(int, int, int);
    friend Timer  &operator+(Timer&, Timer&);
    friend Timer operator-(Timer&, Timer&);
    friend ostream& operator<<(ostream &out, Timer &t);
    friend istream& operator>>(istream &in, Timer &t);
private:
    int hour, minute, second;
};

Timer::Timer()
{
    hour = 0;
    minute = 0;
    second = 0;
}

Timer::Timer(int hour, int minute, int second)
{
    this->hour = hour;
    this->minute = minute;
    this->second = second;
}

Timer & operator+(Timer& a, Timer &b)
{
    a.second = a.second + b.second;
    a.minute = a.minute + b.minute;
    a.hour = a.hour + b.hour;
    if (a.second >= 60)
    {
        a.second = a.second - 60;
        a.minute++;
    }
    if (a.minute >= 60)
    {
        a.minute = a.minute - 60;
        a.hour++;
    }
    return a;
}

Timer operator-(Timer &a, Timer &b)
{
    Timer c;
    c.hour = a.hour - b.hour;
    c.minute = a.minute - b.minute;
    c.second = a.second - b.second;
    if (c.second < 0)
    {
        c.second += 60;
        c.minute--;
    }
    if (c.minute < 0)
    {
        c.minute += 60;
        c.hour--;
    }
    return c;
}

ostream& operator<<(ostream &out, Timer &t)
{
    out << t.hour << ":" << t.minute << ":" << t.second << endl;
    return out;
}

istream& operator>>(istream&in, Timer &t)
{
    cout << "Input hours and minutes." << endl;
    in >> t.hour >> t.minute >> t.second;
    return in;
}

int main()
{
    Timer t1, t2, t3, t4;
    cin >> t1 >> t2;
    cout << "t1=" << t1;
    cout << "t2=" << t2;
    t3 = t1 + t2;
    cout << "t3=t1+t2=" << t3;
    t4 = t1 - t2;
    cout << "t4=t1-t2=" << t4;
    return 0;
}

刚开始我将函数声明为:

friend Timer&operator+(Timer&,Timer&);
friend Timer&operator-(Timer&,Timer&);

对于<<,>>的重载声明的和长代码一样。但是这样做之后我发现出现异常。
在Time &operator+(Timer&t1,Timer&t2)里我声明了一个Timer的局部变量,而当函数调用结束后,该指针变成了悬挂指针。
所以,一定谨记不要在返回值为引用的函数中返回局部变量。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【C++】返回值是类名和返回值是引用的区别 的相关文章

  • 谁能建议我一种在 C++ 中分割名称的简单方法

    我一直在尝试将名称分为名字和姓氏 但我确信我的实现就简单性而言并不是最好的 string name John Smith string first string last name name find getting lastname fo
  • 在实体框架拦截器中向 DbScanExpression 添加内部联接

    我正在尝试使用实体框架 CommandTree 拦截器通过 DbContext 向每个查询添加过滤器 为了简单起见 我有两个表 一个称为 User 有两列 UserId 和 EmailAddress 另一个称为 TenantUser 有两列
  • FileStream 构造函数和默认缓冲区大小

    我们有一个使用 NET 4 用 C 编写的日志记录类 我想添加一个构造函数参数 该参数可以选择设置文件选项 WriteThrough http msdn microsoft com en us library system io fileo
  • EF Core 通过完全替换断开集合导航属性的更新

    使用 EF Core 5 0 我有一个 SPA 页面 可以加载Group实体及其集合Employee来自 API 的实体 var groupToUpdate await context Groups Include g gt g Emplo
  • 如何在 SqlDataReader.Read() 期间从死锁异常中恢复

    我的 NET 应用程序的事件日志显示 它在从 Sql Server 读取数据时偶尔会出现死锁 这种情况通常非常罕见 因为我们已经优化了查询以避免死锁 但有时仍然会发生 过去 我们在调用ExecuteReader函数在我们的SqlComman
  • 时间:2019-03-17 标签:c#ThreadSafeDeepCopy

    我一直在阅读很多其他问题以及大量谷歌搜索 但我一直无法找到明确的解决方案 根据我读过的一些最佳实践 类的静态方法应该创建线程安全的 并且实例成员应该将线程安全留给消费者 我想为该类实现深度复制方法 该类本身还有其他引用类型成员 有没有什么方
  • 动态生成的控件 ID 返回为 NULL

    我可以在 Page PreInit 函数中创建动态控件 如何检索控件及其 ID 我的 C 代码用于创建动态控件之一 var btn new WebForms Button btn Text btn ID Addmore btn Click
  • 如何获取 QTableView 的标题列表?

    我有一个QTableView我的对话框中的对象 我需要访问该表的水平标题并将它们放入QStringList object 尽管进行了大量搜索 但我在 Qt 文档中找不到如何获取此标头列表 编辑 我发现的最接近的地方是this https w
  • 从 WebBrowser 控件 C# 获取滚动值

    我试图在 WebBrowser 控件中获取网页的 Y 滚动索引 但无法访问内置滚动条的值 有任何想法吗 对于标准模式下的 IE 使用文档类型 正如你所说 scrollTop是的财产元素 而不是 HtmlDocument htmlDoc th
  • Visual Studio Code:如何配置 includePath 以获得更好的 IntelliSense 结果

    我是使用 Visual Studio Code 的完全初学者 我不知道我在做什么 我已经四处搜索 也许还不够 但我找不到像我这样的人如何配置的简单解释c cpp properties json每当我单击带有绿色波浪线下划线的行旁边的黄色灯泡
  • 无法在内存位置找到异常源:cudaError_enum

    我正在尝试确定 Microsoft C 异常的来源 test fft exe 中 0x770ab9bc 处的第一次机会异常 Microsoft C 异常 内存位置 0x016cf234 处的 cudaError enum 我的构建环境是 I
  • 运行选定的代码生成器时出错:“未将对象引用设置到对象的实例。”错误?

    我已经尝试了所有解决方案 例如修复 VS 2013 但没有用 当您通过右键单击控制器文件夹来创建控制器并添加控制器时 然后右键单击新创建的控制器的操作并选择添加视图 当我尝试创建视图时 就会发生这种情况 它不是一个新项目 而是一个现有项目
  • cout 和字符串连接

    我刚刚复习了我的 C 我尝试这样做 include
  • 跨多个域的 ASP.NET 会话

    是否有合适的 NET 解决方案来在多个域上提供持久服务器会话 即 如果该网站的用户在 www site1 com 下登录 他们也将在 www site2 com 下登录 安全是我们正在开发的程序的一个问题 Thanks 它是否需要在会话中
  • C++ Streambuf 方法可以抛出异常吗?

    我正在尝试找到一种方法来获取读取或写入流的字符数 即使存在错误并且读 写结束时间较短 该方法也是可靠的 我正在做这样的事情 return stream rdbuf gt sputn buffer buffer size 但如果streamb
  • 矩阵到数组 C#

    这将是转换方阵的最有效方法 例如 1 2 3 4 5 6 7 8 9 into 1 2 3 4 5 6 7 8 9 in c 我在做 int array2D new int 1 2 3 4 5 6 7 8 9 int array1D new
  • 在简单注入器中解析具有自定义参数的类

    我正在使用以下命令创建 WPF MVVM 应用程序简易注射器作为 DI 容器 现在 当我尝试从简单注入器解析视图时遇到一些问题 因为我需要在构造时将参数传递到构造函数中 而不是在将视图注册到容器时 因此这不是适用的 简单注入器将值传递到构造
  • C++0x中disable_if在哪里?

    Boost 两者都有enable if and disable if 但 C 0x 似乎缺少后者 为什么它被排除在外 C 0x 中是否有元编程工具允许我构建disable if按照enable if 哦 我刚刚注意到std enable i
  • 从 JavaScript 中的 OnClientClick 事件中阻止 C# 中的 asp:Button OnClick 事件?

    我有一个asp Button在我的网页上 它调用 JavaScript 函数和代码隐藏方法 后者进行调用以导航到另一个页面 在 JavaScript 函数中 我正在检查条件 如果不满足这个条件 我想中止导航 以便OnClick方法未被调用
  • Java 和/C++ 在多线程方面的差异

    我读过一些提示 多线程实现很大程度上取决于您正在使用的目标操作系统 操作系统最终提供了多线程能力 比如Linux有POSIX标准实现 而windows32有另一种方式 但我想知道编程语言水平的主要不同 C似乎为同步提供了更多选择 例如互斥锁

随机推荐

  • Junit中使用线程池不执行任务代码

    1 在test中使用线程池发送MQ 没有报错 没有执行线程池中的代码 2 查资料 junit框架只要主线程结束完成 单元测试就会关闭 导致线程池中的线程没有执行代码就被销毁关闭了 可以在主线程中sleep一段时间 或者用main方法
  • 稳定ORACLE的执行计划

    很多时候可能我们都希望CBO能够帮我们生成正确 高效的执行计划 但是很多时候事实并非如此 可能因为各种各样的原因 如 统计信息不正确或者CBO天生的缺陷等 都会导致生成的执行计划特别的低效 之前的一家公司有一台专门用于批量做数据校验清洗的数
  • 大学四年自学走来,这些私藏的实用工具/学习网站我贡献出来了

    大学四年 看课本是不可能一直看课本的了 对于学习 特别是自学 善于搜索网上的一些资源来辅助 还是非常有必要的 下面我就把这几年私藏的各种资源 网站贡献出来给你们 主要有 电子书搜索 实用工具 在线视频学习网站 非视频学习网站 软件下载 面试
  • 'vue-cli-service' 不是内部或外部命令,也不是可运行的程序 或批处理文件。

    vue时 报 vue cli service 不是内部或外部命令 也不是可运行的程序 或批处理文件 罪该万死 怎么能忘记 npm install 如果你下载的淘宝镜像 也可以cnpm install 转载于 https www cnblog
  • Java设计模式-状态模式

    1 概述 定义 对有状态的对象 把复杂的 判断逻辑 提取到不同的状态对象中 允许状态对象在其内部状态发生改变时改变其行为 例 通过按钮来控制一个电梯的状态 一个电梯有开门状态 关门状态 停止状态 运行状态 每一种状态改变 都有可能要根据其他
  • STM32F031串口(RS485)中断+DMA发送(预备知识)

    STM32F031串口 RS485 中断 DMA发送 前言 GPIO移植过程 与F1系列的一些区别 串口 DMA 前言 最近在搞STM32F031的项目 F0系列与常用的F1系列有一定区别 在开发过程中遇到一些问题 而且花了好长花间在搜寻解
  • js操作剪贴板讲解

    文章目录 复制 剪切 到剪贴板 Document execCommand Clipboard复制 Clipboard writeText Clipboard write copy cut事件 从剪贴板进行粘贴 document execCo
  • 【E2EL5】A Year in Computer Vision中关于图像增强系列部分

    http www themtank org a year in computer vision 部分中文翻译汇总 https blog csdn net chengyq116 article details 78660521 The M T
  • eclipse修改文字显示大小及html乱码修改编码格式

    1 修改字体大小 2 修改编码格式 html文件出现乱码时需要修改编码格式 备注 有时候修改后还会是乱码 重启eclipse即可
  • 2022年7月3日leetcode每日一题打卡——112.路径总和

    一 题目描述与要求 112 路径总和 力扣 LeetCode 题目描述 给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 判断该树中是否存在 根节点到叶子节点 的路径 这条路径上所有节点值相加等于目标和 target
  • 基于YOLO-V5的结核杆菌目标检测系统【毕业设计,AI+医疗】

    项目背景 结核病 Tuberculosis TB 是由结核分枝杆菌 Mycobacterium tuberculosis 引起的一种慢性人畜共患病 它不受年龄 性别 种族 职业 地区的影响 人体许多器官 系统均可患结核病 其中以肺结核最为常
  • HBase Java 编程

    一 环境配置 1 引入Maven 库
  • JavaScript 中使用Ajax进行网络post请求和get请求

    博主前些天发现了一个巨牛的人工智能学习网站 通俗易懂 风趣幽默 忍不住也分享一下给大家 点击跳转到网站 前言 使用Ajax进行网络请求 默认是异步请求 而且不需要刷新页面 就可以发送请求 获取服务端返回来的数据 一 Ajax的get请求 做
  • apache kafka配置中request.required.acks含义

    Kafka producer的ack有3中机制 初始化producer时的producerconfig可以通过配置request required acks不同的值来实现 0 这意味着生产者producer不等待来自broker同步完成的确
  • 算法--大数开方

    之前已找到比较好的大数乘法算法 现在我们来解决大数开方问题 如有大数n 求其开方x 则x与n必满足x x n 也就是说我们能遍历x找到n的开方 但是问题在于我们是不可能对大数遍历的 如果我们可以确定它的大致范围 仅仅测试几个不容易直接判断的
  • SpringBoot使用Rabbit多消费者削峰

    文章目录 场景 配置 生产者发送消息 消费者处理消息 场景 前端系统推送大批量数据进入我方系统进行处理 为了减轻我方系统的压力 并且充分发挥服务器的性能 提高处理效率 于是使用 Rabbit 做了限流处理 同时有多线程运行多个消费者处理任务
  • QGraphicsItem的缩放

    QGraphicsItem的缩放 QgarphicsItem是Qt视图体系中的项 QGraphicsItem本身是不支持鼠标拖动来缩放的 本文介绍如何通过更改鼠标事件来修改项的大小 本文所用Qt版本为Qt4 8 下文代码实现的功能为 按住s
  • LLVM+clang+VS Code 搭建 C++ 编译环境(windows)

    可参考LLVM clang VS Code 搭建 C 编译环境 windows
  • Bluetooth 蓝牙介绍(七):逻辑链路控制和适配协议规范(L2cap 协议)

    文章目录 前言 L2CAP 特性 前提 术语 常规操作 通道标识符 操作模式 数据包格式 CONNECTION ORIENTED CHANNELS IN BASIC L2CAP MODE CONNECTIONLESS DATA CHANNE
  • 【C++】返回值是类名和返回值是引用的区别

    返回非引用类型 函数的返回值用于初始化在调用函数时创建的临时对象 temporary object 如果返回类型不是引用 在调用函数的地方会将函数返回值复制给临时对象 在求解表达式的时候 如果需要一个地方存储其运算结果 编译器会创建一个没命