简体   繁体   English

功能参数:复制还是指针?

[英]Function parameters: Copy or pointer?

I'm kind of new to C++ and have some questions, this is one of them. 我是C ++的新手并且有一些问题,这是其中之一。

Is there ANY reason when you are using a function that takes in one or several parameters, parameters of which you know will always be stored in a variable before the function call, to pass a copy of the variable, rather than a pointer to the variable? 有没有什么理由当你使用一个函数来接受一个或几个参数时,你知道的参数将始终存储在函数调用之前的变量中,以传递变量的副本,而不是指向变量的指针?

I'm talking in terms of performance. 我在谈论表现。 Seems to me that it would take a lot more resources to pass a copy of a whole struct than just a pointer(4 bytes). 在我看来,传递整个结构的副本而不仅仅是一个指针(4个字节)需要更多的资源。

There are several ways in which passing a copy can be cheaper than passing a pointer. 有几种方法可以传递副本比传递指针更便宜。

  1. The object is equal to or smaller than a pointer. 对象等于或小于指针。 Directly accessing a value will always be faster than dereferencing a pointer. 直接访问值总是比取消引用指针更快。
  2. The structure is small enough to be put on the stack by the compiler. 结构足够小,可以由编译器放在堆栈上。 In this case, access to the values in the structure is done by indexed addressing modes rather than indirect, indexed addressing modes. 在这种情况下,通过索引寻址模式而不是间接索引寻址模式来访问结构中的值。 The former are generally faster. 前者通常更快。

There are other reasons for wanting to pass a copy rather than a reference, namely your function will be making changes in the structure which are not to be reflected back to the caller. 还有其他原因想要传递副本而不是引用,即您的函数将在结构中进行更改,而不会反映回调用者。 While this is generally a poor practice, making the parameter pass-by-value will ensure that the caller's view isn't changed incorrectly. 虽然这通常是一种不好的做法,但使参数按值传递将确保调用者的视图不会被错误地更改。

Now for the part of the answer you probably don't want to hear: It generally doesn't make that much difference! 现在对于你可能不想听到的部分答案:它通常没有那么大的差别! Use the parameter passing method that makes the most sense for the semantics of your program. 使用对程序语义最有意义的参数传递方法。 If you find later that there is a performance bottleneck in a particular area then focus in on improving the performance there. 如果您稍后发现特定区域存在性能瓶颈,那么请专注于提高性能。 Don't over optimize! 不要过度优化!

Passing an object by pointer (or reference) and passing a copy of the same object have different semantics. 通过指针(或引用)传递对象并传递同一对象的副本具有不同的语义。 If you want changes you make on an object to be reflected outside the function call you want reference semantics, otherwise you want value semantics. 如果您希望对对象进行的更改反映在函数调用之外,则需要引用语义,否则您需要值语义。

Commonly value semantics can be expressed either by passing the value by value or by const reference 通常,值语义可以通过值传递值或通过const引用来表示

void value_semantics(my_obj obj);
void value_semantics(const my_obj& obj);

However the const reference way has some drawbacks as well, it prevents several optimizations that the compiler may make because of aliasing issues also for objects with trivial constructors the extra level of indirection (a reference is implemented as a pointer) may outweigh the benefits of avoiding the copy. 然而,const引用方式也有一些缺点,它会阻止编译器可能进行的几个优化,因为对于具有普通构造函数的对象的别名问题 ,额外的间接级别(引用被实现为指针)可能超过避免的好处副本。

In order to get reference semantics you can choose either passing by reference or by pointer, as others already said references are more natural than pointers in C++ (you don't have to use the address of operator & ) and the only real advantage of pointers is if you want to enable NULL values. 为了获得引用语义,您可以选择通过引用传递或通过指针传递,因为其他人已经说过引用比C ++中的指针更自然(您不必使用运算符的地址& )以及指针的唯一真正优势是否要启用NULL值。

The rule of thumb is that for non-trivial classes you should pass by const reference, otherwise by value. 经验法则是,对于非平凡的类,您应该通过const引用传递,否则通过值传递。

A pointer opens up for bugs, since it allows the callee to alter the object. 一个指针为bug打开,因为它允许被调用者改变对象。 Pointers can be 0, which tends to create crashes, and this creates a need to test for 0 pointers all over the place, this can be annoying. 指针可能为0,这往往会导致崩溃,这就需要在整个地方测试0指针,这可能很烦人。 Using C++ references, const -declared where possible, circumvents both these problems. 使用C ++引用, const -declared尽可能避免这两个问题。

避免使用pointer.Use常量引用if是IN参数否则只是IN OUT参数的引用

The main question isn't about performance, but semantics, and whether your function modifies the data in the structure. 主要问题不是性能,而是语义,以及您的函数是否修改了结构中的数据。

If your function modifies the structure, then passing a pointer will let the caller see the changed data in the structure. 如果您的函数修改了结构,那么传递指针将让调用者看到结构中已更改的数据。 In this case, passing a copy will likely be wrong, since your function will modify a copy which is then (presumably) discarded. 在这种情况下,传递副本可能是错误的,因为您的函数将修改一个然后(可能)丢弃的副本。 Of course, it is possible that your function modifies the data, but you don't want the modifications, in which case a copy is the right thing to do, to protect the original values from changes. 当然,您的函数可能会修改数据,但您不希望进行修改,在这种情况下,复制是正确的操作,以保护原始值不受更改的影响。

If your function doesn't modify the structure, then there's no reason to copy the values, since they will only be read. 如果您的函数没有修改结构,那么没有理由复制值,因为它们只会被读取。

If you are not comfortable with the concept of passing pointers to structures, you should get some practice, because it is the typical way of dealing with structures in C and C++. 如果你不熟悉将指针传递给结构的概念,你应该做一些练习,因为它是处理C和C ++结构的典型方法。

As far as performance goes, it's more work to copy the structure, but it's fairly minor in the scheme of things. 就性能而言,复制结构需要做更多的工作,但在方案中却相当小。 Keep your mind on the semantics of the code first. 首先要考虑代码的语义。

引用更常见,如果它们不会改变,则引用const引用。

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

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