当我使用按引用返回时,我不知道这些代码之间的区别
I don't know the difference between these codes when I use return-by-reference
我正在学习面向对象编程。 我不知道这些代码之间的区别。 它们都使用按引用返回,但代码#1运行良好,但代码#2运行不佳。 教授说,当我存储交换函数的返回值时,代码#2有问题,它导致了问题。 但我不知道为什么。
请告诉我为什么以及两个代码的区别。
代码 #1:
#include <iostream>
using namespace std;
struct Pair {
int first;
int second;
};
Pair& swap(Pair&);
int main()
{
Pair p1 = {10, 20};
Pair p2 = swap(p1);
return 0;
}
Pair& swap(Pair& pair)
{
int temp;
temp = pair.first;
pair.first = pair.second;
pair.second = temp;
return pair;
}
代码 #2:
#include <iostream>
using namespace std;
struct Pair {
int first;
int second;
};
Pair& swap(int num1, int num2);
int main()
{
Pair p = swap(10, 20);
return 0;
}
Pair& swap(int num1, int num2)
{
int temp;
temp = num1;
num1 = num2;
num2 = temp;
Pair pair = {num1, num2};
return pair;
}
不同之处在于,在代码 #1 中,main()
函数声明变量pair
,因此它存在于main()
的范围内。在代码 #2 中,swap()
函数声明变量pair
,因此它仅存在于swap()
函数的范围内,一旦您离开交换函数,变量就会被销毁。
首先,您可以避免不必要的代码:
int temp = num1;
num1 = num2;
num2 = temp;
Pair pair = {num1, num2};
为什么要先交换数字,只需创建交换数字的对:
Pair pair = {num2, num1};
// ^ ^
但是现在让我们考虑一下差异(我删除了与问题无关的所有部分,即实际交换(:
Pair& swap(Pair& pair)
{
return pair;
}
在第一个变体中,您通过引用获得一对。该对必须在外部创建并传递到函数中:
Pair p; // created outside
swap(p); // swap uses reference to p outside
// p still exists
// swap returns just a reference to the same p it received
// -> you can use it for assignment:
Pair pp = swap(p);
请注意,您的函数交换了它通过引用收到的原始 p,因此 p 和 pp 都包含相同的内容。所以这两个代码片段是等效的:
Pair p;
Pair pp = swap(p);
Pair p;
swap(p); // ignoring the return value
Pair pp = p;
在第二个变体中,您在函数中创建对!
Pair& swap(int num1, int num2)
{
Pair pair = {num1, num2};
return pair;
}
但是该货币对的生命周期随着函数退出而结束。因此,您返回对实际上已被销毁的一对的引用,这会产生未定义的行为。
如果您按值接受该对,则会发生完全相同的情况:
Pair& swap(Pair pair) // not a reference -> pair is copied into local variable
{
return pair; // returning reference to local -> undefined behaviour!
}
在所有情况下,您都需要返回局部变量,您需要按值返回它们:
Pair swap(int, int)
{
Pair pair;
return pair; // return by value, value will be copied into target variable
// (actually, due to copy elision, directly written there)
}
如果您不想修改传递给函数的对,则按值返回也很有用(只是为了完整起见,并不是您需要将函数更改为(。但是,然后,您将确保不会修改传递给的对。您可以通过 const 引用接受并在其中创建副本;但是,最简单的方法是按值接受,这会在接收参数时直接创建副本:
Pair swap(Pair pair) // notice: both references dropped
{
return pair;
};
现在,p 和 pp确实不同(当然,假设您实际实现了交换(:
Pair p;
Pair pp = swap(p);
#code2 对仅存在于交换函数范围内
在 #code1 中,您需要一个临时值,因为您可以更改存在对,并且您希望在更改之前保存该值。 在 #code2(让我们忽略主要问题(中,您只需从您获得的价值中形成对
Pair& swap(int num1, int num2)
{
Pair pair = {num1, num2};
return pair;
}
如果你考虑一下,你不会交换对,因为你没有配对。
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值
- 我不知道为什么这段代码会让核心被转储?
- 我不知道如何使用代码块win32 gui
- DirectX 11 引擎在第三次代码改进后没有突然运行,我不知道为什么
- 我看过Stellarium代码,我不知道它从哪里开始
- C++ 我不知道此代码中的输出过程(父类子级)
- 由于某种原因,我的代码中出现了 [json.exception.type_error.302]。我知道错误意味着什么,但我不知道哪里有故障
- 我正在制作c ++代码,但发生错误我不知道为什么
- 当我使用按引用返回时,我不知道这些代码之间的区别
- 我不知道ROS代码的含义,也看不懂ros维基的例子
- 我不知道为什么只有一个代码在两个代码之间具有sigsegv(看起来相同)
- 我的代码结果为零,我不知道为什么
- 我不知道这个 MCMF 代码有什么问题
- C++代码出现分段错误,我不知道为什么
- 我不知道如何使用 boost,虽然我的老师确实提供了代码,但我遇到了一个错误
- C ++我不知道为什么这个迭代器在我的代码中不起作用
- 代码不会继承,我不知道为什么
- 我不知道为什么 for 循环不适用于此代码
- 欧拉#8项目,我不知道为什么我的代码给出了荒谬的高值
- 我不知道为什么我不能循环整个代码?当我按 y 时"next customer"