C++|函数三种传参、返回方式的优势、劣势及适用场合

C++|函数三种传参、返回方式的优势、劣势及适用场合By default, non-pointer arguments in C++ are passed by value.

大家好,欢迎来到IT知识分享网。

By default, non-pointer arguments in C++ are passed by value. When an argument is passed by value, the argument’s value is copied into the value of the corresponding function parameter.

默认情况下,C++中的非指针参数是通过值传递的。按值传递参数时,参数的值将复制到相应函数参数的值中。

While pass by value is suitable in many cases, it has a couple of limitations. First, when passing a large struct or class to a function, pass by value will make a copy of the argument into the function parameter. In many cases, this is a needless performance hit, as the original argument would have sufficed. Second, when passing arguments by value, the only way to return a value back to the caller is via the function’s return value. While this is often suitable, there are cases where it would be more clear and efficient to have the function modify the argument passed in. Pass by reference solves both of these issues.

虽然值传递在许多情况下都适用,但它有一些限制。首先,当向函数传递大型结构或类时,值传递会将参数复制到函数参数中。在许多情况下,这是一个不必要的性能消耗,因为原始参数已经足够了。其次,当按值传递参数时,将值返回给调用者的唯一方法是通过函数的返回值。虽然这通常是合适的,但在某些情况下,让函数修改传入的参数会更清楚、更有效。“按引用传递”解决了这两个问题。

There is one more way to pass variables to functions, and that is by address. Passing an argument by address involves passing the address of the argument variable rather than the argument variable itself. Because the argument is an address, the function parameter must be a pointer. The function can then dereference the pointer to access or change the value being pointed to.

还有一种方法可以将变量传递给函数,那就是按地址传递。按地址传递参数涉及传递参数变量的地址,而不是参数变量本身。因为参数是地址,所以函数参数必须是指针。然后,该函数可以取消对访问指针的引用或更改所指向的值。

1 Pros and cons of pass by value

1.1 Advantages of passing by value:

In most cases, pass by value is the best way to accept parameters of fundamental types when the function does not need to change the argument. Pass by value is flexible and safe, and in the case of fundamental types, efficient.

1.1.1 Arguments passed by value can be variables (e.g. x), literals (e.g. 6), expressions (e.g. x+1), structs & classes, and enumerators. In other words, just about anything.

1.1.2 Arguments are never changed by the function being called, which prevents side effects.

1.2 Disadvantages of passing by value:

Copying structs and classes can incur a significant performance penalty, especially if the function is called many times.

1.3 When to use pass by value:

When passing fundamental data type and enumerators, and the function does not need to change the argument.

1.4 When not to use pass by value:

When passing structs or classes (including std::array, std::vector, and std::string).

2 Pros and cons of pass by reference

2.1 Advantages of passing by reference:

2.1.1 References allow a function to change the value of the argument, which is sometimes useful. Otherwise, const references can be used to guarantee the function won’t change the argument.

2.1.2 Because a copy of the value of argument is not made(only address), pass by reference is fast, even when used with large structs or classes.

2.1.3 References can be used to return multiple values from a function (via out parameters).

2.1.4 References must be initialized, so there’s no worry about null values.

2.2 Disadvantages of passing by reference:

2.2.1 Because a non-const reference cannot be initialized with a const l-value or an r-value (e.g. a literal or an expression), arguments to non-const reference parameters must be normal variables.

2.2.1 It can be hard to tell whether an argument passed by non-const reference is meant to be input, output, or both. Judicious use of const and a naming suffix for out variables can help.

2.2.1 It’s impossible to tell from the function call whether the argument may change. An argument passed by value and passed by reference looks the same. We can only tell whether an argument is passed by value or reference by looking at the function declaration. This can lead to situations where the programmer does not realize a function will change the value of the argument.

2.3 When to use pass by reference:

When passing structs or classes (use const if read-only).

When you need the function to modify an argument.

When you need access to the type information of a fixed array.

2.4 When not to use pass by reference:

When passing fundamental types that don’t need to be modified (use pass by value).

Rule: Use pass by (const) reference instead of pass by value for structs and classes and other expensive-to-copy types.

3 Pros and cons of pass by address

3.1 Advantages of passing by address:

3.1.1 Pass by address allows a function to change the value of the argument, which is sometimes useful. Otherwise, const can be used to guarantee the function won’t change the argument. (However, if you want to do this with a non-pointer, you should use pass by reference instead).

3.1.1 Because a copy of the argument is not made, it is fast, even when used with large structs or classes.

3.1.1 We can return multiple values from a function via out parameters.

3.2 Disadvantages of passing by address:

3.2.1 Because literals and expressions do not have addresses, pointer arguments must be normal variables.

3.2.1 All values must be checked to see whether they are null. Trying to dereference a null value will result in a crash. It is easy to forget to do this.

3.2.1 Because dereferencing a pointer is slower than accessing a value directly, accessing arguments passed by address is slower than accessing arguments passed by value.

3.3 When to use pass by address:

3.3.1 When passing built-in arrays (if you’re okay with the fact that they’ll decay into a pointer).

3.3.1 When passing a pointer and nullptr is a valid argument logically.

3.4 When not to use pass by address:

3.4.1 When passing a pointer and nullptr is not a valid argument logically (use pass by reference and dereference the pointer argument).

3.4.1 When passing structs or classes (use pass by reference).

3.4.1 When passing fundamental types (use pass by value).

As you can see, pass by address and pass by reference have almost identical advantages and disadvantages. Because pass by reference is generally safer than pass by address, pass by reference should be preferred in most cases.

Rule: Prefer pass by reference to pass by address whenever applicable.

4 Return by value

Return by value is the simplest and safest return type to use. When a value is returned by value, a copy of that value is returned to the caller. As with pass by value, you can return by value literals (e.g. 5), variables (e.g. x), or expressions (e.g. x+1), which makes return by value very flexible.

Another advantage of return by value is that you can return variables (or expressions) that involve local variables declared within the function without having to worry about scoping issues. Because the variables are evaluated before the function returns, and a copy of the value is returned to the caller, there are no problems when the function’s variable goes out of scope at the end of the function.

Return by value is the most appropriate when returning variables that were declared inside the function, or for returning function arguments that were passed by value. However, like pass by value, return by value is slow for structs and large classes.

4.1 When to use return by value:

When returning variables that were declared inside the function

When returning function arguments that were passed by value

4.2 When not to use return by value:

When returning a built-in array or pointer (use return by address)

When returning a large struct or class (use return by reference)

5 Return by address

Returning by address involves returning the address of a variable to the caller. Similar to pass by address, return by address can only return the address of a variable, not a literal or an expression (which don’t have addresses). Because return by address just copies an address from the function to the caller, return by address is fast.

However, return by address has one additional downside that return by value doesn’t — if you try to return the address of a variable local to the function, your program will exhibit undefined behavior.

Return by address is often used to return dynamically allocated memory to the caller.

5.1 When to use return by address:

When returning dynamically allocated memory

When returning function arguments that were passed by address

5.2 When not to use return by address:

When returning variables that were declared inside the function or parameters that were passed by value (use return by value)

When returning a large struct or class that was passed by reference (use return by reference)

6 Return by reference

Similar to pass by address, values returned by reference must be variables (you should not return a reference to a literal or an expression that resolves to a temporary value, as those will go out of scope at the end of the function and you’ll end up returning a dangling reference,and the style like the the return value for return a noc_local variable). When a variable is returned by reference, a reference to the variable is passed back to the caller. The caller can then use this reference to continue modifying the variable, which can be useful at times. Return by reference is also fast, which can be useful when returning structs and classes.

However, just like return by address, you should not return local variables .

6.1 When to use return by reference:

6.1.1 When returning a reference parameter

6.1.2 When returning an element from an array that was passed into the function

6.1.3 When returning a large struct or class that will not be destroyed at the end of the function (e.g. one that was passed in)

6.2 When not to use return by reference:

6.2.1 When returning variables that were declared inside the function or parameters that were passed by value (use return by value)

6.2.2 When returning a built-in array or pointer value (use return by address)

reference: https://www.learncpp.com/cpp-tutorial/72-passing-arguments-by-value/

-End-

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/57453.html

(0)

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信