C ++直接将返回的引用传递给函数

时间:2015-03-03 22:02:18

标签: c++ function reference return

你能看看这两个例子,并解释一下为什么打印结果的第一次尝试给了我错误的数字?

第一个例子(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'时,它可以正常工作,但我的目标是得到这样的东西:

  • function getInt创建对象,将其放在向量中(所以我只调用v.emplace_back())并返回对当前添加对象的引用(v.back())
  • getInt返回的
  • 值传递给printRes,后者使用文件
  • 中的值填充对象

我不想创建时间变量如't',而是将vector元素直接传递给printRes函数,但在我更加扩展的情况下,我在析构函数中崩溃(或者有时在某些随机位置)。

1 个答案:

答案 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()返回的迭代器都会失效,因此您不应该将它存储太长时间。但是,立即使用它,就像这里一样,很好。