首页 > 其他分享 >引用不可作为局部变量的返回值

引用不可作为局部变量的返回值

时间:2023-11-04 21:45:08浏览次数:35  
标签:p1 return mem 局部变量 Person 引用 operator 返回值

1.概述

由于引用实际上是指向被引用变量的一个隐式指针,而局部变量在返回后就会被销毁,我指向的内容被销毁了,这个隐式指针也就成了野指针,导致错误

2.实例

错误写法

以下是我在运算符重载时使用引用作为局部变量返回值导致的问题:
Person& operator+ (Person &t);
{
Person p;
p.mem_a = mem_a + t.mem_a;
p.mem_b = mem_b + t.mem_b;
return p;
}
Person operator=(Person &p1)
{
this->mem_a = p1.mem_a;
this->mem_b = p1.mem_b;
return *this;
}

例子是 p1 = p1 + p2;
这里根据运算符优先级原则, 先进行+的运算,然后返回局部变量p的一个引用,也就是指向局部变量p的一个隐式指针
随后局部变量p被释放, 该指针变为野指针,指向未知。
之后我们进行 = 的运算,将该隐式指针作为参数,但是其现在已经指向未知,所以导致程序卡在这里引发错误。

正确写法

Person operator+ (Person &t);
{
Person p;
p.mem_a = mem_a + t.mem_a;
p.mem_b = mem_b + t.mem_b;
return p;
}
Person operator=(Person p1)
{
this->mem_a = p1.mem_a;
this->mem_b = p1.mem_b;
return this;
}
/
例子是 p1 = p1 + p2;
这里根据运算符优先级原则, 先进行+的运算,然后返回局部变量p的一个拷贝,随后局部变量p被释放。
之后我们进行 = 的运算,将该拷贝p作为参数,能够正确执行后续步骤。

具体有关返回值的讨论请参考关于返回值的几种情况

代码

//
// Created by trmbh on 2023-11-04.
//
#include <iostream>

class Person{
public:
    friend std::ostream & operator<<(std::ostream &cout, Person &p);
    friend Person operator ++(Person &p);
    Person(){
        mem_a = 0;
        mem_b = 0;
    }

    Person(int a, int b){
        mem_a = a;
        mem_b = b;
    }

    Person operator+ (Person &t)
    {
        Person p;
        p.mem_a = mem_a + t.mem_a;
        p.mem_b = mem_b + t.mem_b;
        return p; //不能返回局部变量的引用。局部变量会在函数返回后被销毁,因此被返回的引用就成为了”无所指”的引用,类似于野指针
    }

    /* 浅拷贝 */
    Person operator=(Person p1){
        this->mem_a = p1.mem_a;
        this->mem_b = p1.mem_b;
        return *this;
    }

/*    Person& operator+ (Person &t)
    {
        Person p;
        p.mem_a = mem_a + t.mem_a;
        p.mem_b = mem_b + t.mem_b;
        return p;
        //不能返回局部变量的引用。局部变量会在函数返回后被销毁,因此被返回的引用就成为了”无所指”的引用,类似于野指针
        //返回的引用类似一个隐式指针
    }

    *//* 浅拷贝 *//*
    Person operator=(Person p1){
        this->mem_a = p1.mem_a;
        this->mem_b = p1.mem_b;
        return *this;
    }*/
private:
    int mem_a;
    int mem_b;
};

std::ostream& operator<<(std::ostream &cout, Person &p){
    using namespace std;
    cout << "这里a的值为:" << p.mem_a << std::endl << "这里b的值为:" << p.mem_b << std::endl;
    return cout;
}

Person operator ++(Person &p){
    Person p1;
    p1.mem_a = p.mem_a++;
    p1.mem_b = p.mem_b++;
    return p1;
}


int main(){
    using namespace std;
    Person p1(1,2);
    Person p2(2, 1);
    p1 = p1 + p2;
    cout << p1;

    p2 = ++p1;
    cout << p1;
    
    return 0;
}

标签:p1,return,mem,局部变量,Person,引用,operator,返回值
From: https://www.cnblogs.com/trmbh12/p/17809817.html

相关文章

  • 关于返回值的几种情况
    1.参考链接:关于返回值的几种情况2.思路在一个函数的内部,return的时候返回的都是一个拷贝,不管是变量、对象还是指针都是返回拷贝,但是这个拷贝是浅拷贝。如果返回一个基本类型的变量,比如:inta;a=5;returna;那么就会a的一个拷贝,即5返回,然后a就被销毁了。尽管a被销毁了,但......
  • UE4蓝图对Actor的引用
    通过关卡蓝图调用在关卡中放置一个Actor,在关卡蓝图中右键createareferencetoactor,即可注意使用该方法创建时,需要现在关卡中选择上该类Actor当Actor生成时创建其的引用当我们在蓝图中利用SpawnActorfromClass生成Actor节点返回值拖出promotetovariable,提升为变量即可......
  • 无涯教程-MongoDB - 数据库引用
    如MongoDB关系的最后一章所示,为了在MongoDB中实现规范化的数据库结构,无涯教程使用了引用关系的概念,也称为ManualReferences,其中无涯教程手动将参考文件的ID存储在其他文件中。但是,如果文档包含来自不同集合的引用,则可以使用MongoDBDBRefs。使用DBRefDBRefs中有三个字段-......
  • JavaScript 函数、函数构造、函数调用、参数、函数返回值、变量的作用域、预解析
    一、函数及函数的构造函数是一个可重用的代码块,用来完成某个特定功能。每当需要反复执行一段代码时,可以利用函数来避免重复书写相同代码。函数包含着的代码只能在函数被调用时才会执行,就可以避免页面载入时执行该脚本简单来说就是一个封装,封装的是一个特定的功能,重复使用函......
  • 使用Spring Data JPA,您可以通过定义接口,面来避免Object[]以更优雅的格式返回数据,sql
    使用SpringDataJPA,您可以通过定义接口,面来避免Object[]以更优雅的格式返回数据,sql的返回值和接口的属性名一致。jap会根据sql返回值映射到接口对应属性。cas*_*lin6根据定义,JPA将返回Object[]查询返回带有投影的列表的列表,即来自实体(或多个实体)的一组字段.使用......
  • 左值引用和右值引用
    高级架构工程师C++进阶课程(内存泄漏、面试、开源框架、协程、STL、C++11新特性、即时通讯)_哔哩哔哩_bilibili什么是左值可以在等号左边,可以取地址,具名intmain(intargc,charconst*argv[]){inti=0;++i=10;(i+=10)=1000;cout<<i<<endl;......
  • 问题描述:未能加载文件或程序集或它的某一个依赖项。找到的程序集清单定义与程序集引用
    报错原因:    版本不统一问题 解决方法:    右键打开“管理解决方案的NuGet程序包”--->将项目引用的程序包版本改统一(一般情况下用最新稳定版) ......
  • java 基本数据类型和引用数据类型
    ......
  • 查看python中import可以支持的格式引用
    importimportlib.machineryformat_list=importlib.machinery.all_suffixes()print(format_list)so是linux可以加载的文件,windows是pyc ......
  • java中方法内的局部变量是在什么时候被创建的
    2023.10.291.不是局部变量在该方法被执行/调用时创建,而是应该为在该变量被声明并赋值时创建,可以理解为“当代码执行到该变量被赋值的代码时才被创建”。栈会为每个方法在运行的时候分配一块独立的栈帧内存区域,栈帧又包含“局部变量表”、“操作数栈”、“动态链接”以及“方法出......