简体   繁体   English

在C ++中通过引用传递一组结构

[英]Passing an array of structs by reference in C++

So I'm still rather new to programming/C++, and still trying to wrap my head around pointers and passing by reference and everything. 所以我仍然是编程/ C ++的新手,并且仍然试图绕过指针并通过引用和所有内容传递。 A program I'm trying to figure out now needs to pass an array of structs to another function. 我想弄清楚的一个程序现在需要将一个结构数组传递给另一个函数。 I've gotten it working by just passing the array directly there. 我已经通过直接传递数组来实现它。 It seems to work fine. 它似乎工作正常。 However, what I'm concerned about is that I believe I'm passing it by value, and I understand that it's better to pass structs by reference, so you're not making a copy of the struct every time... 但是,我关心的是我相信我是按值传递它的,并且我理解通过引用传递结构更好,所以你不是每次都复制结构...

Anyway, here's a basic example of what I'm doing: 无论如何,这是我正在做的一个基本的例子:

struct GoldenHelmet {
    int foo;
    string bar;
    };

void pass (GoldenHelmet ofMambrino[], int size);

int main () {
    GoldenHelmet ofMambrino[10];
    int size = sizeof(ofMambrino) / sizeof(ofMambrino[0]);
    ofMambrino[1].foo = 1;
    pass(ofMambrino, size);
    cout << ofMambrino[2].foo << endl;
    return 0;
}

void pass (GoldenHelmet ofMambrino[], int size) {
    ofMambrino[2].foo = 100;
    ofMambrino[2].bar = "Blargh";
}

From what I understand, it works because arrays are already pointers, right? 根据我的理解,它的工作原因是数组已经是指针,对吧? But the way I have that configured, am I still passing a copy of the struct and everything to the pass() function? 但是我配置的方式,我仍然传递结构的副本和所有东西到pass()函数? I've tried to pass it by reference, but it doesn't seem to want to work any way I've tried. 我试图通过引用传递它,但它似乎不想以任何方式工作我尝试过。

The C++ way: C ++方式:

#include <array>

typedef std::array<GoldenHelmet, 10> Helmets;

void pass(Helmets &);

int main()
{
   Helmets h;
   h[1].foo = 1;
   pass(h);
   //...
}

void pass(Helmets & h)
{
   h[2].foo = 100;
   // ...
}

Indeed, we pass the array by reference. 实际上,我们通过引用传递数组。

This syntax: 这个语法:

void pass (GoldenHelmet ofMambrino[], int size)

is actually quite confusing. 实际上很混乱。 Because you are not passing an array, you are passing a pointer. 因为您没有传递数组,所以传递指针。 They are not the same thing though, don't get confused. 它们不是一回事,不要混淆。 This oddity only applies to function parameters. 这种奇怪仅适用于功能参数。 The above is exactly identical to this: 以上与此完全相同:

void pass (GoldenHelmet * ofMambrino, int size)

It's actually impossible to pass an array by value, unless it is a sub-object of another object. 实际上不可能按值传递数组,除非它是另一个对象的子对象。 You can pass them by reference, you need to include the size though, but you can do that using a template: 您可以通过引用传递它们,但是您需要包含大小,但是您可以使用模板来执行此操作:

template<int N>
void pass (GoldenHelmet (&ofMambrino)[N])

These are all possible, but none of them are pass by value. 这些都是可能的,但它们都没有通过值。 Just think of ofMambrino as being the address of the beginning of the array, and that is what you are passing. 试想一下, ofMambrino是数组开头的地址,这就是你所传递的。

void pass (GoldenHelmet ofMambrino[], int size)
void pass (GoldenHelmet ofMambrino[10], int size)
void pass (GoldenHelmet *ofMambrino, int size)
void pass (GoldenHelmet (&ofMambrino)[10], int size)

Arrays are represented and passed as pointers, so you are not copying anything here. 数组被表示并作为指针传递,因此您不会在此处复制任何内容。 In contrast, if you were passing a single struct , it would be passed by value. 相反,如果您传递的是单个 struct ,则它将按值传递。

Below is a code snippet to illustrate this last point: 下面是一个代码片段,用于说明最后一点:

void passByVal (GoldenHelmet ofMambrino) {
    ofMambrino.foo = 100;
    ofMambrino.bar = "Blargh";
}

void passByRef (GoldenHelmet& ofMambrino) {
    ofMambrino.foo = 100;
    ofMambrino.bar = "Blargh";
}

int main() {
    GoldenHelmet h;
    passByVal(h); // h does not change
    passByRef(h); // fields of h get assigned in the call
}

First of all array is not pointers. 首先,数组不是指针。 We refer this as a pointer in the argument list because when we use 我们将其称为参数列表中的指针,因为我们使用时

int x[ ]

x is actually const pointer that points the beginning of the array. x实际上是指向数组开头的const指针。 And when you pass this to a function you send the adress of the memory that is beginning of the array. 当你将它传递给一个函数时,你会发送数组开头的内存地址。 Thats why when you make a change in your function, you make change in the adress of your variable in the caller section actually. 这就是为什么当你对函数进行更改时,实际上在调用者部分中对变量的地址进行了更改。 This is actualy simulated call by reference not call by reference. 这是通过参考实际模拟调用而不是通过引用调用。 But effect is same with call by reference because you are working on memory locations. 但是效果与引用调用相同,因为您正在处理内存位置。 For this reason when you send array of your struct you pass actually adress of your array of structs. 因此,当您发送结构数组时,实际上会传递结构数组的地址。 Thats why when you change value on this, you actually change your structs. 这就是为什么当你改变它的价值时,你实际上改变你的结构。

To use call by reference, one thing you must to do is to define your function prototype like 要通过引用使用调用,您必须做的一件事是定义您的函数原型

void f(int &param)

and when calling function, it is same with the others. 在调用函数时,它与其他函数相同。

To summarize: 总结一下:

int main()
{
     int x;

     // simulated call by reference that use adress of variable, 
     // lets say adress of x is 19ff 
     f(&x);     // actually you send 19ff

     f(x);      // call by reference that use reference of variable

}

// simulated call by reference
void f(const int *y)
{
    // when you use like *y=10, you are writing on memory area 19ff, you actually 
    // change memory area that is belong to x in the main

}

// call by reference
void f(const int &y)
{
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM