通过引用传递 c++

发布于 2024-08-21 06:39:27 字数 191 浏览 4 评论 0原文

我的 C++ 老师告诉我,只有当我不打算更改函数内数组上的任何内容时,才应使用引用调用。 我在程序中传递了一些非常大的向量。所有向量都将在函数内修改。我的矩阵的大小约为 [256*256][256][50]...

是否有某些特殊原因不在这里使用调用引用?

AFAIK 通过引用调用应该更快并且消耗更少的内存?

My teacher in c++ told me that call by reference should only be used if I'm not going to change anything on the arrays inside the function.
I have some really big vectors that I'm passing around in my program. All the vectors will be modified inside the functions. My matrices are of sizes about [256*256][256][50]...

Is there some particular reason not to use call-by reference here?

AFAIK call by reference should be way faster and consume less memory?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

ヤ经典坏疍 2024-08-28 06:39:27

除了关于何时以及如何传递非基本类型可能的 const 引用的所有常见讨论之外,数组在这里非常特殊。

由于与 C 的向后兼容性,并且由于您的具体问题:数组可能很大,数组在 C 或 C++ 中永远不会真正按值传递。该数组将衰减为指向第一个元素的指针,因此当您编写时:

void foo( type array[100] );

编译器实际上正在处理:

void foo( type *array );

无论数组的大小是多少(有两个常见的陷阱:相信arrayfoo 中的一个数组,并且相信它上面有 100 个元素。

现在,在 C++ 中,您实际上可以通过引用传递数组,但引用必须是 的。数组的具体类型,包括大小:

void foo_array( type (&array)[100] );

有趣的语法告诉编译器该函数将采用恰好包含 100 个 type 类型元素的数组,其优点是编译器可以执行。为您检查大小:

// assuming 'type' is defined
int main() {
   type array0[99];
   type array1[100];

   foo( array0 );     // compiles, but if size=100 is assumed it will probably break
                      // equivalent to: foo( &array0[0] )
   // foo2( array0 ); // will not compile, size is not 100
   foo2( array1 );    // compiles, size is guaranteed to be 100
}

现在,问题是您的函数仅适用于恰好包含 100 个元素的数组,并且在某些情况下,您可能希望在不同的数组大小中执行相同的操作。两种解决方案是:模板化函数。在数组的大小中,这将为每个使用的大小提供大小安全的实现——更长的编译时间和二进制大小,为每个不同的大小编译模板——或者使用按值传递语法,这将使数组衰减——大小不安全,必须作为额外参数传递,更少的编译时间和二进制大小。第三种选择是将两者结合起来:

void foo( type *array, int size );
template <size_t N>
void foo( type (&array)[N] ) {
   foo( array, N );
}

在这种情况下,虽然每种大小都会有一个模板化的 foo,但编译器很可能会内联调用,并且生成的代码将相当于调用者提供数组和尺寸。真实数组不需要额外的计算和类型安全。

现在,数组很少使用引用传递。

Besides all common discussions on when and how to pass by possibly const reference for non-primitive types, arrays are quite special here.

Due to backwards compatibility with C, and there due to your specific problem: arrays can be huge, arrays are never really passed by value in either C or C++. The array will decay into a pointer to the first element, so when you write:

void foo( type array[100] );

The compiler is actually processing:

void foo( type *array );

Regardless of what the size of the array is (two common pitfalls there: trusting that array is an array inside foo and believing that it will be guaranteed to be 100 elements on it.

Now, in C++ you can actually pass arrays by reference, but the reference must be of the concrete type of the array, that includes the size:

void foo_array( type (&array)[100] );

The funny syntax there is telling the compiler that the function will take an array of exactly 100 elements of type type. The advantage there is that the compiler can perform size checking for you:

// assuming 'type' is defined
int main() {
   type array0[99];
   type array1[100];

   foo( array0 );     // compiles, but if size=100 is assumed it will probably break
                      // equivalent to: foo( &array0[0] )
   // foo2( array0 ); // will not compile, size is not 100
   foo2( array1 );    // compiles, size is guaranteed to be 100
}

Now, the problem is that your function will only work for an array of exactly 100 elements, and in some cases, you might want to perform the same operation in different array sizes. The two solutions are: template the function in the size of the array which will provide a size-safe implementation for each used size --greater compile time and binary size, the template is compiled for every different size-- or using the pass-by-value syntax, which will make the array decay --not safe in size, that must be passed as extra argument, lesser compile time and binary size. A third option is combining both:

void foo( type *array, int size );
template <size_t N>
void foo( type (&array)[N] ) {
   foo( array, N );
}

In this case, while there will be one templated foo for each size, the compiler will most probably inline the call and the generated code would be equivalent to the caller providing the array and size. No extra computations needed and type safety for real arrays.

Now, pass-by-reference is very rarely used with arrays.

心如狂蝶 2024-08-28 06:39:27

我的 C++ 老师告诉我,只有当我不打算更改函数内数组上的任何内容时,才应使用引用调用。

当您不更改函数内部的某些内容您更改内容并希望将更改反映到原始数组不关心更改时,应使用它反映在原始数组中。

如果您希望函数更改原始数组(您需要在调用后保留原始值)并且被调用函数更改传递参数的值,则不应使用它。

My teacher in c++ told me that call by reference should only be used if I'm not going to change anything on the arrays inside the function.

It should be used when you are not changing something inside the function or you change things and want the changes to be reflected to the original array or don't care about the changes to be reflected in the original array.

It shouldn't be used if you don't want your function to change your original array (you need to preserve the original values after the call) and the callee function changes the values of the passed argument.

自演自醉 2024-08-28 06:39:27

你的老师错了。如果您需要修改数组,则可以通过引用传递。如果您不想修改某些内容,请通过 const 引用传递。

Your teacher is wrong. If you need to modify arrays, pass by reference is the way to go. If you don't want something modified, pass by const reference.

离去的眼神 2024-08-28 06:39:27

为了防止意外更改,请使用 pass-by-const-reference;这样,默认情况下*,传入的数组不能被调用的函数更改。

* 可以用const_cast覆盖。

To prevent accidental changes, use pass-by-const-reference; that way, by default*, the passed-in array can't get changed by the called function.

* Can be overridden with const_cast.

爱给你人给你 2024-08-28 06:39:27

如果满足以下条件,则可以按引用传递:

  1. 您不会修改传递的对象
  2. 您想要修改对象并且不想保持旧对象不变

当您按引用传递某些内容时,只有指针会传递给函数。如果你传递整个对象,那么你需要复制它,所以它会消耗更多的CPU和内存。

You can pass by reference if:

  1. you won't modify passed object
  2. you want to modify object and don't want to keep old object untouched

When you pass something by reference, then only pointer is passed to function. If you pass whole object then you need to copy it, so it will consume more cpu and memory.

梦亿 2024-08-28 06:39:27

一般来说,对象应该始终通过引用传递。否则将生成对象的副本,如果对象很大,这将影响性能。

现在,如果您调用的方法或函数不修改对象,则最好按如下方式声明该函数:

void some_function(const some_object& o);

如果您尝试在函数体内修改对象的状态,则会生成编译错误。

还应该注意的是,数组总是通过引用传递。

Generally speaking, objects should always be passed by reference. Otherwise a copy of the object will be generated and if the object is substantially big, this will affect performance.

Now if the method or function you are calling does not modify the object, it is a good idea to declare the function as follows:

void some_function(const some_object& o);

This will generate a compile error if you attempt to modify the object's state inside the function body.

Also it should be noted that arrays are always passed by reference.

不疑不惑不回忆 2024-08-28 06:39:27

等一下..我很害怕人们如何回答这个问题。据我所知,数组总是通过引用传递。

void function(int array[])
{
    std::cout << array[0] << '\n';
}

// somewhere else..
int array[2] = { 1, 2 };
function(array); // No copy happens here; it is passed by reference

此外,您不能明确地说数组参数是引用,因为这将是创建引用数组的语法(这是不允许的)。

void function(int &array[]) // error here
{ /* ... */ }

那么你是什么意思?

此外,许多人说只有在修改函数内数组的内容时才应该这样做。那么,const 引用呢?

void function(const int arr[])
{
    std::cout << arr[0] << '\n';
}

-- 编辑

有人请指出我如何在 C++ 中通过引用传递数组吗?

-- 编辑

哦,所以你在谈论向量。好的,那么经验法则是:

  • 仅当您想要修改向量的内容时才通过引用传递。
  • 尽可能传递对 const 的引用。
  • 仅当所讨论的对象非常非常小(例如,包含整数的结构),或者有意义时(我无法想出具体情况),才按值传递。

我错过了什么吗?

-- 编辑

  • 对于纯 C 数组,当您想确保该数组具有给定的确定大小。

谢谢,德里比亚斯。

Hold on a second.. I'm scared at how people are answering this one. Arrays, as far as I remember, are always passed by reference.

void function(int array[])
{
    std::cout << array[0] << '\n';
}

// somewhere else..
int array[2] = { 1, 2 };
function(array); // No copy happens here; it is passed by reference

Further, you can't say the array argument is a reference explicitly, as that would be the syntax for creating an array of references (something that's not allowed).

void function(int &array[]) // error here
{ /* ... */ }

So what do you mean?

Further, many are saying that you should only do that if you modify the contents of the array inside the function. Then, what about reference-to-const?

void function(const int arr[])
{
    std::cout << arr[0] << '\n';
}

-- edit

Will somebody please point me out how to not pass an array by reference in C++?

-- edit

Oh, so you're talking about vectors. Okay, then the rules of thumb are:

  • Pass by reference only when you want to modify the contents of the vector.
  • Pass by reference-to-const whenever you can.
  • Pass by value only when the object in question is really, really small (like a struct containing an integer, for example), or when it makes sense to (can't think of a case out of the top of my head).

Did I miss something?

-- edit

  • In the case of plain C arrays, it's a good idea to pass them by reference (like in void function(int (&array)[100])) when you want to ensure that the array has a given definite size.

Thanks, dribeas.

何其悲哀 2024-08-28 06:39:27

通常,在入门课程中,他们会告诉您这一点,这样您就不会意外更改您不想更改的内容。

就像如果您通过引用传递 userName,并且不小心将其更改为 mrsbuxley,这可能会导致错误,或者至少会在以后造成混乱。

Usually, in introductory courses, they tell you that so you don't accidentally change something you didn't want to.

Like if you passed in userName by reference, and accidentally changed it to mrsbuxley that probably would cause errors, or at the very least be confusing later on.

标点 2024-08-28 06:39:27

我看不出有什么理由不能通过引用传递。或者,您可以传递指针,但我认为有时通过引用传递更好,因为它可以避免空指针异常。

如果你的老师建议这是某种约定,那么如果有意义的话,请随意打破它。您始终可以在函数上方的注释中记录这一点。

I don't see any reason why you can't pass by reference. Alternatively you could pass pointers around, but I think pass by reference is better sometimes as it avoids null pointer exceptions.

If your teacher has suggested this as some kind of convention, then feel free to break it if it makes sense to. You can always document this in a comment above the function.

坐在坟头思考人生 2024-08-28 06:39:27

我们的风格是永远不要按值传递对象,而总是传递引用或 const 引用。我们不仅拥有可以包含数百 MB 数据的数据结构,并且按值传递将成为应用程序杀手,而且如果我们按值传递 3D 点和向量,我们的应用程序也会陷入停滞。

Our house style is to NEVER pass an object by value but to always pass a reference or const reference. Not only do we have data structures that can contain 100s of MB of data and pass by value would be an application killer, but also if we were passing 3D points and vectors by value the our applications would grind to a halt.

蓝天 2024-08-28 06:39:27

通过引用传递对象总是一个不错的选择,但我们需要小心,首先我们必须决定我们的函数的目的/目的是什么?

你必须在这里做出选择,我们是只读取对象的数据还是修改它。

假设你有一个像这样的接口

void increament_value(int& a);

,你可以修改我们传递的对象的值,但是当你传递敏感数据时这是一场灾难,你可能会丢失原始数据并且无法恢复它,对吗?

因此,C++ 为您提供了一种功能,可以不更改您将其引用传递给函数的对象的值,并且传递对象的 const 引用始终是一个不错的选择,例如,

double get_discounted_amount(const double &amount,double discount){
    return (amount*discount/100);
}

This保证你的对象的实际值不会改变,但这又取决于你的接口的目的,你是想改变它还是只使用(读取)它

It is always a good choice to pass object by reference but we need to be careful and first we have to decide what is our purpose/ purpose of our function?

You have to make a choice here, whether we are gonna only read the data of an object or modify it.

Suppose you got an interface like

void increament_value(int& a);

so in this you can modify value an object which we are passing, but it is a disaster when you passing your sensitive data, you might lose you original data and can not revert it, right?

so c++ provides you a functionality to not to change the value of an object whose reference you are passing to a function, and it is always a good choice to pass a const reference of an object for e.g.,

double get_discounted_amount(const double &amount,double discount){
    return (amount*discount/100);
}

This guarantees that your actual value of an object is not gonna change, but again it depends on purpose of your interface whether you wanna change it or only use(read) it

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文