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

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;
}

posted @ 2023-11-04 21:37  DawnTraveler  阅读(22)  评论(0编辑  收藏  举报