在c ++中通过引用返回

时间:2011-07-05 06:32:49

标签: c++ reference

#include<iostream>
using namespace std;

int& add() {

    static int a;
    a++;
    cout<<"\na="<<a;
    return a;
}

int main {

   int x,y,m;
   int &z = add(); //it behaves as a reference to "a" which is a static variable
   x=add();//why does it work correctly
   y=add();//why does it work correctly
   z++;
   m=add();//why does it work correctly
   cout<<"\nx="<<x<<"\ny="<<y<<"\nz="<<z<<"\nm="<<m;
   return 0;
}

output:
a=1
a=2
a=3
a=5
x=2
y=3
z=5
m=5

  

内部恰好发生了什么    x,y,m&amp; ž

7 个答案:

答案 0 :(得分:3)

int main{
    int x,y,m;      // declare three ints:  x,y,m, all unassigned
    int &z = add(); // a is incremented to 1, z is a reference to a
    x=add();        // add() returns a reference to a, x copies the value of a
    y=add();        // same as above
    z++;            // increments a, since z is a reference to a
    m=add();        // same as x and y, copies the value of a
    cout<<"\nx="<<x<<"\ny="<<y<<"\nz="<<z<<"\nm="<<m;
    return 0;
}

所以你连续三次调用add(),将a增加到1,2,3(并且每次打印该值。

z是对真实a的引用。

xym是作业分配时a的值的副本。所以x是2,y是3,我们通过z++跳过4,然后m是5。

答案 1 :(得分:3)

int &z = add();

z是对静态变量a的引用。从现在开始,az是同义词。它们都指向相同的内存位置。

int x;
x = add();

x是一个独立的内存位置。由于分配,x将在调用时保留add()个返回值。这就是ym的工作原理。

答案 2 :(得分:2)

xym只是变量,因此它们会在调用a时获得add中的任何值,这就是它。如果要更改任何变量的值,则不会影响a的值。由于z是引用,因此它是静态a变量的“指针”(在某种意义上),因此更改z实际上会更改a

答案 3 :(得分:2)

引用是某个对象的另一个名称,别名。它就像对象一样。

add()返回对a的引用时,其行为就像返回的值 a一样。

所以代码

x = add();

表现得像以前一样

a++;
x = a;

因此它捕获了a此时的值。

另一方面,代码

int& z = add();

表现得像

a++;
int& z = a;

z成为a的另一个名称。从现在开始使用az并不重要,这意味着相同。仍然只有一个值,但该值有两个名称。我们可以使用其中任何一个来阅读或更新它。

就像我们使用Bob来引用一个名叫Robert的人一样 - 这个名字也是同一个东西。

答案 4 :(得分:1)

我相信这是它的工作原理:

在上下文中使用的引用,其中需要引用类型的(值)被隐式取消引用。这包括(其中包括):

  • 分配给变量
  • 传递按值
  • 声明的函数参数
  • 传递按值
  • 声明的函数返回值

在上面的上下文中,创建了引用值的副本。

无论何处需要引用,它们都被视为引用(显然不会被解除引用)。这包括:

  • 初始化兼容类型的引用
  • 传递由引用
  • 声明的函数参数
  • 如果通过引用声明,则传递函数返回值

在这些上下文中,不会创建引用值的副本。新引用只是现有值的新别名。

上述两种情境的语法是相同的,因此需要付出一些努力来查看正在发生的事情。

答案 5 :(得分:1)

引用只是一个常量指针,在某种意义上说,你可以改变指向的对象,但你不能指向其他东西。

当您需要值并允许使用*而不是.来访问成员时,C ++所做的只是让您免于添加指向解引用语法(一元->)指向结构化的类型。

请注意,C ++中有一个使用const X&的常见反模式,就好像这是一种比X更智能的函数参数。请永远不要忘记引用基本上是指针,因此指向对象在使用时可能会改变甚至消失(const并不意味着对象不会改变,只是你不能改变它使用它参考)。

有关在使用引用而非值时应注意的原因的更详细说明,请参阅this answer

每当你看到一个引用时,你应该至少考虑一下,如果对象在你使用它的时候足够活跃和/或变异。在您的情况下,引用的对象是一个静态函数,因此生命周期没有问题(函数静态对象在您第一次进入定义它们的范围时就会出现,直到程序结束为止。)

将代码翻译成实际发生的事情(指针摆弄)

#include<iostream>
using namespace std;

int* add() {
    static int a;
    a++;
    cout << "\na=" << a;
    return &a; // we're returning a pointer to our static variable
}

int main(int argc, const char *argv[]) {
   int x,y,m;
   int *z = add(); // points to "a" which is a static variable
   x = *add();     // just get the current value of (incremented) a
   y = *add();     // same here, of course now different from x
   (*z)++;         // incrementing a from outside the function (we've a pointer!)
   m = *add();     // once again just reading current incremented value
   cout << "\nx=" << x << "\ny=" << y<< "\nz=" << (*z) << "\nm=" << m;
   return 0;
}

答案 6 :(得分:1)

好的,让我们剖析这个小程序

int& add() 
{
   static int a;
   a++;
   cout<<"\na="<<a;
   return a;
}

static int a声明一个变量。此上下文中的静态意味着只存储a,并且只要调用add,就会使用该位置。所以a就像一个只能在add中访问的全局变量。

返回值是参考。大多数编译器内部使用指针来表示引用。你在这里看到的是返回对静态变量a的引用。一旦获得参考,任何人都可以更改。

a ++和cout很简单 - 这里没有进一步的评论。

int main{
    int x,y,m;      // declare three ints:  x,y,m, all unassigned
    int &z = add(); // a is incremented to 1, z is a reference to a
    x=add();        // add() returns a reference to a, x copies the value of a
    y=add();        // same as above
    z++;            // increments a, since z is a reference to a
    m=add();        // same as x and y, copies the value of a
    cout<<"\nx="<<x<<"\ny="<<y<<"\nz="<<z<<"\nm="<<m;
    return 0;
}

int&amp; z = add();调用add - 这意味着a递增。 z现在是静态变量a的别名,因为它使用了引用。 X =添加();再次增加a但现在复制a的值,因为x不是int&amp;类型但是类型为int。哟 - 相同。 z ++:因为z是a的别名 - 增加a而不通过cout打印它。

m = add():增加a,复制像m和y一样的int。

一旦你理解为什么x,y,m是副本而z是别名,输出就很简单。

还有问题吗?

问候

托拜厄斯