你能看看这两个例子,并解释一下为什么打印结果的第一次尝试给了我错误的数字?
第一个例子(printRes通过指针传递x):
int& getInt(int x){
x++;
cout << "int " << x << endl;
return x;
}
void printRes(int *x){
cout << "res " << *x << endl;
}
int main()
{
int t = getInt(5);
printRes(&getInt(5)); // first attemp
printRes(&t); // second attemp
return 0;
}
第二个例子(printRes通过引用传递x):
int& getInt(int x){
x++;
cout << "int " << x << endl;
return x;
}
void printRes(int &x){
cout << "res " << x << endl;
}
int main()
{
int t = getInt(5);
printRes(getInt(5)); // first attemp
printRes(t); // second attemp
return 0;
}
结果:
int 6
int 6
res 2686640
res 6
当我通过值传递'x'时,它可以正常工作,但我的目标是得到这样的东西:
我不想创建时间变量如't',而是将vector元素直接传递给printRes函数,但在我更加扩展的情况下,我在析构函数中崩溃(或者有时在某些随机位置)。
答案 0 :(得分:0)
第一次调用printRes()给出错误结果的原因是getInt()有一个严重的缺陷。
问题是getInt()返回对局部变量的引用,而这在C ++中是不行的。 getInt()返回时,变量x不再存在,对变量的任何引用都变为无效。结果是printRes()在行中接收的指针:
printRes(&getInt(5));
最有可能指向废话。第二个例子也是如此。
第二次调用printRes()给出正确结果的原因是运气。在行中返回无效引用时:
int t = getInt(5);
变量t使用x的值初始化,并且因为它在getInt()返回后立即发生,所以存储x的内存尚未被覆盖。
无论如何,返回引用是你应该谨慎的。查看Is the practice of returning a C++ reference variable, evil?
执行所需操作的一种方法是定义一个在getInt()中不是本地的向量v(因此它可以存在于函数范围之外)并返回迭代器。像这样:
#include <iostream>
#include <vector>
using namespace std;
vector<int> v;
vector<int>::iterator getInt(int x){
x++;
cout << "int " << x << endl;
v.emplace_back(x);
return --v.end(); // end() points to after last element.
// Decrement to get the last element
}
void printRes(vector<int>::iterator i){
cout << "res " << *i << endl;
*i = 99; //set the element to a new value if you want
}
int main()
{
printRes(getInt(5));
return 0;
}
请注意,每当使用v.emplace_back()(或类似函数)时,从getInt()返回的迭代器都会失效,因此您不应该将它存储太长时间。但是,立即使用它,就像这里一样,很好。