如何在C ++中使用参考参数? [英] How do I use Reference Parameters in C++?

查看:151
本文介绍了如何在C ++中使用参考参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想了解如何使用参考参数。在我的文本中有几个例子,但是它们太复杂,我不明白为什么和如何使用它们。任何人都可以给我一个最基本的例子,如何/为什么使用一个,也许有或没有它的差别(如果没有附加'&'会发生什么)。



例如,如果我创建了一个函数:int doSomething(int& a,int& b),不会放入'&
$ b

我理解,使用引用变量是为了改变一个formal->引用,然后允许双向交换参数。然而,这是我的知识的程度,更具体的例子将是很有帮助。

解决方案

将参考视为别名。当你在一个引用上调用某个东西时,你实际上是在引用所引用的对象上调用它。

  int i; 
int& j = i; // j是i的别名b
$ b j = 5; //与as = 5相同

关于函数,请考虑:

  void foo(int i)
{
i = 5;
}

上面, int i 是一个值,传递的参数通过值传递 。这意味着如果我们说:

  int x = 2; 
foo(x);

i x 的。因此将 i 设置为5对 x 没有效果,因为它是 / code>正在更改。但是,如果我们使 i 引用:

  void foo ; i)// i是变量的别名
{
i = 5;
}

然后说 foo(x)不再创建 x 的副本; i x 。因此,如果我们说 foo(x),在函数 i = 5; $ c> x = 5; x 更改。



希望澄清有点。






为什么这很重要?编程时,您从不要复制和粘贴代码。你想做一个功能,做一个任务,它做得很好。每当这个任务需要执行,你就使用那个函数。



所以让我们假设我们要交换两个变量。这看起来像这样:

  int x,y; 

// swap:
int temp = x; //存储x
的值x = y; // make x等于y
y = temp; // make y等于x的旧值

好吧,太好了。我们想让这个函数,因为: swap(x,y); 更容易阅读。所以,让我们试试这个:

  void swap(int x,int y)
{
int temp = X;
x = y;
y = temp;
}

这不行!问题是,这是交换两个变量的副本。也就是:

  int a,b; 
swap(a,b); // hm,x和y是a和b的副本... a和b保持不变

在C中,引用不存在,解决方案是传递这些变量的地址;也就是使用指针*:

  void swap(int * x,int * y)
{
int temp = * x;
* x = * y;
* y = temp;
}

int a,b;
swap(& a,& b);

这很好。然而,它有点笨拙使用,实际上有点不安全。 swap(nullptr,nullptr),交换两个nothings和dereference空指针...未定义的行为!可以通过一些检查修复:

  void swap(int * x,int * y)
{
if (x == nullptr || y == nullptr)
return; // one is null;这是一个无意义的操作

int temp = * x;
* x = * y;
* y = temp;
}

但是看起来我们的代码笨拙。 C ++引入了解决这个问题的参考。如果我们只是别名一个变量,我们得到我们寻找的代码:

  void swap(int& x,int& y)
{
int temp = x;
x = y;
y = temp;
}

int a,b;
swap(a,b); // inside,x and y are really a and b

(我们不能意外传入一个null,没有null引用。)这是因为在函数内发生的交换真的发生在函数外的别名的变量。



(注意,不要写 swap 函数:) < algorithm>






另一个用途是删除当您调用时发生的副本一个函数。考虑我们有一个非常大的数据类型。复制此对象需要很多时间,我们希望避免这种情况:

  struct big_data 
{char data [9999999]; }; // 大!

void do_something(big_data data);

big_data d;
do_something(d); // ouch,make a copy of all that data:<

但是,我们真正需要的是变量的别名, (再次,在C中,我们传递大数据类型的地址,解决复制问题,但引入笨拙。):

  void do_something(big_data& data); 

big_data d;
do_something(d); //没有副本!数据别名d在函数内

这就是为什么你会听到它说你应该通过引用传递的东西所有的时间,除非它们是原始类型。 (因为内部传递别名可能是用指针完成的,就像在C中一样。对于小对象,它只是更快地使副本然后担心指针。)



注意你应该是正确的。这意味着如果你的函数不修改参数,标记为 const 。如果上面的 do_something 只看过但没有改变 data ,我们将它标记为 const

  void do_something(const big_data& data); // alias a big_data,不要改变它

我们避免复制 / em>我们说嘿,我们不会修改这个。



相比之下,我们的 swap

/ code>函数不能 const ,因为我们确实修改了别名。



一些更多。






*粗糙指针教程:



指针是一个保存另一个变量的地址的变量。例如:

  int i; // normal int 

int * p; //指向一个整数(不是整数!)
p =& i; //& i表示i的地址。 p指向i

* p = 2; // * p表示dereference p。也就是说,这到达p(i)指向的int
//,并将其设置为2.

所以,如果你看到指针版本交换函数,我们传递我们想要交换的变量的地址,然后我们做交换,取消引用获取和设置值。


I am trying to understand how to use reference parameters. There are several examples in my text, however they are too complicated for me to understand why and how to use them. Could anyone give me the MOST basic example of how/why to use one, and perhaps the difference with or without it (what would happen if you didn't attach the '&').

for example, if I've created a function: int doSomething(int& a, int& b), what would be the consequences of not putting in that '&.'

I understand that reference variables are used in order to change a formal->reference, which then allows a two-way exchange of parameters. However, that is the extent of my knowledge, and a more concrete example would be of much help.

解决方案

Think of a reference as an alias. When you invoke something on a reference, you're really invoking it on the object to which the reference refers.

int i;
int& j = i; // j is an alias to i

j = 5; // same as i = 5

When it comes to functions, consider:

void foo(int i)
{
    i = 5;
}

Above, int i is a value and the argument passed is passed by value. That means if we say:

int x = 2;
foo(x);

i will be a copy of x. Thus setting i to 5 has no effect on x, because it's the copy of x being changed. However, if we make i a reference:

void foo(int& i) // i is an alias for a variable
{
    i = 5;
}

Then saying foo(x) no longer makes a copy of x; i is x. So if we say foo(x), inside the function i = 5; is exactly the same as x = 5;, and x changes.

Hopefully that clarifies a bit.


Why is this important? When you program, you never want to copy and paste code. You want to make a function that does one task and it does it well. Whenever that task needs to be performed, you use that function.

So let's say we want to swap two variables. That looks something like this:

int x, y;

// swap:
int temp = x; // store the value of x
x = y;        // make x equal to y
y = temp;     // make y equal to the old value of x

Okay, great. We want to make this a function, because: swap(x, y); is much easier to read. So, let's try this:

void swap(int x, int y)
{
    int temp = x;
    x = y;
    y = temp;
}

This won't work! The problem is that this is swapping copies of two variables. That is:

int a, b;
swap(a, b); // hm, x and y are copies of a and b...a and b remain unchanged

In C, where references do not exist, the solution was to pass the address of these variables; that is, use pointers*:

void swap(int* x, int* y)
{
    int temp = *x;
    *x = *y;
    *y = temp;
}

int a, b;
swap(&a, &b);

This works well. However, it's a bit clumsy to use, and actually a bit unsafe. swap(nullptr, nullptr), swaps two nothings and dereferences null pointers...undefined behavior! Fixable with some checks:

void swap(int* x, int* y)
{
    if (x == nullptr || y == nullptr)
        return; // one is null; this is a meaningless operation

    int temp = *x;
    *x = *y;
    *y = temp;
}

But looks how clumsy our code has gotten. C++ introduces references to solve this problem. If we can just alias a variable, we get the code we were looking for:

void swap(int& x, int& y)
{
    int temp = x;
    x = y;
    y = temp;
}

int a, b;
swap(a, b); // inside, x and y are really a and b

Both easy to use, and safe. (We can't accidentally pass in a null, there are no null references.) This works because the swap happening inside the function is really happening on the variables being aliased outside the function.

(Note, never write a swap function. :) One already exists in the header <algorithm>, and it's templated to work with any type.)


Another use is to remove that copy that happens when you call a function. Consider we have a data type that's very big. Copying this object takes a lot of time, and we'd like to avoid that:

struct big_data
{ char data[9999999]; }; // big!

void do_something(big_data data);

big_data d;
do_something(d); // ouch, making a copy of all that data :<

However, all we really need is an alias to the variable, so let's indicate that. (Again, back in C we'd pass the address of our big data type, solving the copying problem but introducing clumsiness.):

void do_something(big_data& data);

big_data d;
do_something(d); // no copies at all! data aliases d within the function

This is why you'll hear it said you should pass things by reference all the time, unless they are primitive types. (Because internally passing an alias is probably done with a pointer, like in C. For small objects it's just faster to make the copy then worry about pointers.)

Keep in mind you should be const-correct. This means if your function doesn't modify the parameter, mark it as const. If do_something above only looked at but didn't change data, we'd mark it as const:

void do_something(const big_data& data); // alias a big_data, and don't change it

We avoid the copy and we say "hey, we won't be modifying this." This has other side effects (with things like temporary variables), but you shouldn't worry about that now.

In contrast, our swap function cannot be const, because we are indeed modifying the aliases.

Hope this clarifies some more.


*Rough pointers tutorial:

A pointer is a variable that holds the address of another variable. For example:

int i; // normal int

int* p; // points to an integer (is not an integer!)
p = &i; // &i means "address of i". p is pointing to i

*p = 2; // *p means "dereference p". that is, this goes to the int
        // pointed to by p (i), and sets it to 2.

So, if you've seen the pointer-version swap function, we pass the address of the variables we want to swap, and then we do the swap, dereferencing to get and set values.

这篇关于如何在C ++中使用参考参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆