在 C++ 中通过引用传递对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18147038/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 21:45:35  来源:igfitidea点击:

passing object by reference in C++

c++classobjectsyntax

提问by KNU

The usual way to pass a variable by referencein C++(also C) is as follows:

在 C++(也包括 C)中通过引用传递变量的常用方法如下:

void _someFunction(dataType *name){ // dataType e.g int,char,float etc.
/****
definition
*/
}

int main(){
    dataType v;
    _somefunction(&v);  //address of variable v being passed
    return 0;
}

But to my surprise, I noticed when passing an object by referencethe name of object itself serves the purpose(no &symbol required) and that during declaration/definition of function no *symbol is required before the argument. The following example should make it clear:

但令我惊讶的是,我注意到当通过引用传递对象时,对象本身的名称可以达到目的(不需要&符号),并且在函数的声明/定义期间*,参数前不需要符号。下面的例子应该清楚:

// this
#include <iostream>
using namespace std;

class CDummy {
  public:
    int isitme (CDummy& param);     //why not (CDummy* param);
};

int CDummy::isitme (CDummy& param)
{
  if (&param == this) return true;
  else return false;
}

int main () {
  CDummy a;
  CDummy* b = &a;
  if ( b->isitme(a) )               //why not isitme(&a)
    cout << "yes, &a is b";
  return 0;
}

I have problem understanding why is this special treatment done with class . Even structures which are almost like a class are not used this way. Is object name treated as address as in case of arrays?

我无法理解为什么要对 class 进行这种特殊处理。即使是几乎像类的结构也不是这样使用的。对象名称是否像数组一样被视为地址?

回答by keyser

What seems to be confusing you is the fact that functions that are declared to be pass-by-reference (using the &) aren't called using actual addresses, i.e. &a.

似乎让您感到困惑的是,声明为传递引用(使用&)的函数并未使用实际地址调用,即&a.

The simple answer is that declaring a function as pass-by-reference:

简单的答案是将函数声明为传递引用:

void foo(int& x);

is all we need. It's then passed by reference automatically.

这就是我们所需要的。然后它会自动通过引用传递。

You now call this function like so:

你现在像这样调用这个函数:

int y = 5;
foo(y);

and ywill be passed by reference.

并将y通过引用传递。

You could also do it like this (but why would you? The mantra is: Use references when possible, pointers when needed) :

你也可以这样做(但为什么要这样做?口头禅是:尽可能使用引用,需要时使用指针):

#include <iostream>
using namespace std;

class CDummy {
public:
    int isitme (CDummy* param);
};


int CDummy::isitme (CDummy* param)
{
    if (param == this) return true;
    else return false;
}

int main () {
    CDummy a;
    CDummy* b = &a;             // assigning address of a to b
    if ( b->isitme(&a) )        // Called with &a (address of a) instead of a
        cout << "yes, &a is b";
    return 0;
}

Output:

输出:

yes, &a is b

回答by Mats Petersson

A reference is really a pointer with enough sugar to make it taste nice... ;)

一个引用实际上是一个含有足够糖分的指针,让它尝起来很好吃......;)

But it also uses a different syntax to pointers, which makes it a bit easier to use references than pointers. Because of this, we don't need &when calling the function that takes the pointer - the compiler deals with that for you. And you don't need *to get the content of a reference.

但它也使用与指针不同的语法,这使得使用引用比使用指针更容易一些。因此,&在调用带指针的函数时我们不需要- 编译器会为您处理。而且您不需要*获取参考的内容。

To call a reference an alias is a pretty accurate description - it is "another name for the same thing". So when ais passed as a reference, we're really passing a, not a copy of a- it is done (internally) by passing the address of a, but you don't need to worry about how that works [unless you are writing your own compiler, but then there are lots of other fun things you need to know when writing your own compiler, that you don't need to worry about when you are just programming].

将引用称为别名是一个非常准确的描述 - 它是“同一事物的另一个名称”。因此,当a作为引用传递时,我们实际上传递的是a,而不是 的副本a- 它是通过传递 的地址(在内部)完成的a,但是您无需担心它是如何工作的[除非您正在编写自己的编译器,但是在编写自己的编译器时,您还需要了解许多其他有趣的事情,您在编程时无需担心]。

Note that references work the same way for intor a classtype.

请注意,引用对intclass类型的工作方式相同。

回答by SeanRamey

Ok, well it seems that you are confusing pass-by-reference with pass-by-value. Also, C and C++ are different languages. C doesn't support pass-by-reference.

好吧,看来您将引用传递与值传递混淆了。此外,C 和 C++ 是不同的语言。C 不支持传递引用。

Here are two C++ examples of pass by value:

以下是按值传递的两个 C++ 示例

// ex.1
int add(int a, int b)
{
    return a + b;
}

// ex.2
void add(int a, int b, int *result)
{
    *result = a + b;
}

void main()
{
    int result = 0;

    // ex.1
    result = add(2,2); // result will be 4 after call

    // ex.2
    add(2,3,&result); // result will be 5 after call
}

When ex.1is called, the constants 2and 2are passed into the function by making local copies of them on the stack. When the function returns, the stack is popped off and anything passed to the function on the stack is effectively gone.

调用 ex.1 时,常量22通过在堆栈上制作它们的本地副本传递给函数。当函数返回时,栈被弹出,栈上传递给函数的任何东西实际上都消失了。

The same thing happens in ex.2, except this time, a pointer to an intvariable is also passed on the stack. The function uses this pointer (which is simply a memory address) to dereference and change the value at that memory address in order to "return" the result. Since the function needs a memory address as a parameter, then we must supply it with one, which we do by using the &"address-of" operator on the variable result.

同样的事情发生在ex.2 中,除了这次,一个指向int变量的指针也在堆栈上传递。该函数使用此指针(它只是一个内存地址)来取消引用并更改该内存地址处的值,以便“返回”结果。由于函数需要一个内存地址作为参数,所以我们必须为它提供一个,我们通过&在变量上使用“address-of”运算符来实现result

Here are two C++ examples of pass-by-reference:

以下是传递引用的两个 C++ 示例

// ex.3
int add(int &a, int &b)
{
    return a+b;
}

// ex.4
void add(int &a, int &b, int &result)
{
    result = a + b;
}

void main()
{
    int result = 0;

    // ex.3
    result = add(2,2); // result = 2 after call
    // ex.4
    add(2,3,result); // result = 5 after call
}

Both of these functions have the same end result as the first two examples, but the difference is in how they are called, and how the compiler handles them.

这两个函数的最终结果与前两个示例相同,但不同之处在于它们的调用方式以及编译器如何处理它们。

First, lets clear up how pass-by-reference works. In pass-by-reference, generally the compiler implementation will use a "pointer" variable in the final executable in order to access the referenced variable, (or so seems to be the consensus) but this doesn't have to be true. Technically, the compiler can simply substitute the referenced variable's memory address directly, and I suspect this to be more true than generally believed. So, when using a reference, it could actually produce a more efficient executable, even if only slightly.

首先,让我们弄清楚传递引用是如何工作的。在传递引用中,编译器实现通常会在最终可执行文件中使用“指针”变量来访问引用的变量,(或者似乎是共识),但这不一定是真的。从技术上讲,编译器可以简单地直接替换引用变量的内存地址,我怀疑这比通常认为的更真实。因此,当使用引用时,它实际上可以产生更高效的可执行文件,即使只是轻微的。

Next, obviously the way a function is called when using pass-by-reference is no different than pass-by-value, and the effect is that you have direct access to the original variables within the function. This has the result of encapsulation by hiding the implementation details from the caller. The downside is that you cannot change the passed in parameters without also changing the original variables outside of the function. In functions where you want the performance improvement from not having to copy large objects, but you don't want to modify the original object, then prefix the reference parameters with const.

接下来,很明显,使用引用传递时调用函数的方式与值传递没有什么不同,其效果是您可以直接访问函数内的原始变量。这具有通过对调用者隐藏实现细节来进行封装的结果。缺点是你不能改变传入的参数而不改变函数外部的原始变量。在您希望通过不必复制大对象来提高性能但又不想修改原始对象的函数中,然后在引用参数前加上const.

Lastly, you cannot change a reference after it has been made, unlike a pointer variable, and they must be initialized upon creation.

最后,与指针变量不同,您不能在创建后更改引用,并且必须在创建时对其进行初始化。

Hope I covered everything, and that it was all understandable.

希望我涵盖了所有内容,并且这一切都是可以理解的。

回答by Uchia Itachi

Passing by reference in the above case is just an aliasfor the actual object.

在上述情况下通过引用传递只是alias针对实际对象。

You'll be referring to the actual object just with a different name.

您将使用不同的名称来指代实际对象。

There are many advantages which referencesoffer compared to pointer references.

有许多优点references相比提供pointer references

回答by LukeCodeBaker

One thing that I have to add is that there is no reference in C.

我必须补充的一件事是 C 中没有引用。

Secondly, this is the language syntax convention. & - is an address operator but it also mean a reference - all depends on usa case

其次,这是语言语法约定。& - 是地址运算符,但也意味着引用 - 一切都取决于美国情况

If there was some "reference" keyword instead of & you could write

如果有一些“引用”关键字而不是 & 你可以写

int CDummy::isitme (reference CDummy param)

but this is C++ and we should accept it advantages and disadvantages...

但这是 C++,我们应该接受它的优点和缺点......