In-depth analysis of C ++ reference parameters

Source: Internet
Author: User

Declaring a parameter as a reference actually changes the default passing mechanism of passing parameters by value. When passing parameters by value, the function operates on a local copy of the real parameter.

I. Three common usage of referenced parameters:

1. Change the value of the real parameter, such as swap (). When a parameter is referenced, the function receives the left value of the real parameter rather than the copy of the value. This means that the function knows the location of the real parameter in the memory, so it can change its value or obtain its address.
2. Return additional results to the main function. For example:

/*************************************** * ******************* Description: the second method for passing test references * Author: Charley * datetime: * compile environment: win7 32-bit + vs2008 *********************************** * **********************/# include <iostream> # include <vector> using namespace STD; // The reference parameter 'occurs' can contain the second returned value vector <int>: const_iterator look_up (const vector <int> & VEC, int value, // is the value in the vector?? Int & occurs) // how many times? {// Res_iter is initialized to the next position vector of the last element <int >:: const_iterator res_iter = Vec. end (); occurs = 0; For (vector <int>: const_iterator iter = Vec. begin (); iter! = Vec. end (); ++ ITER) {// determines whether valueif (* iter = value) exists {// This item is valid only when value is found for the first time; // when the second value is found, res_iter has been assigned a value by the next step. The value is not valid. // when the value appears multiple times, if (res_iter = Vec. end () res_iter = ITER; ++ occurs ;}}// if the value cannot be found, a returned iteratorreturn res_iter pointing to the next position of the last element of the vector ;} /*** call the look_up Method */INT main_test6 () {vector <int> vints; int ival; cout <"enter a number and press Ctrl + Z to finish: "<Endl; while (CIN> ival) vints. push _ Back (ival); If (vints. Size () = 0) {cout <"No element. "<Endl; Return-1 ;}cout <" The result is as follows: "<Endl; For (vector <int >:: const_iterator iter = vints. begin (); iter! = Vints. end (); ITER ++) cout <* ITER <"\ t"; cout <Endl; int occurs = 0; // check whether the container contains value 2. Vector <int>: const_iterator resiter = look_up (vints, 2, occurs); If (! Occurs) {cout <"container does not contain 2. "<Endl;} else {cout <" container 2 appears: "<occurs <" Times, * iterator is: "<* resiter <Endl;} return 0 ;}

3. transfer large class objects to functions. For example:

Class huge {public: Double Stuff [1000] ;};
Extern int calc (const huge &);
Int main (){
Huge table [2, 1000];
 
//... Initialize table
Int sum = 0;
For (int ix = 0; ix <1000; ++ IX)
// Function calc () specifies the array element pointing to the huge type as the real Parameter
Sum + = calc (Table [ix]);
 
//...
}

2. If the referenced parameter does not want to be modified inside the called function, declaring the parameter as a reference of the const type is a good method.

For example:

Class X;
Extern int foo_BAR (X &);
 
Int Foo (const X & XX ){
// Error: const passed to non-const
Return foo_BAR (XX );
}
To make thisProgramBy compiling, we can change the type of the foo_BAR () parameter. The following two declarations are acceptable.
Extern int foo_BAR (const X &);
Extern int foo_BAR (x); // pass by value

 

Alternatively, you can pass a copy of XX to allow foo_BAR () to change it.
Int Foo (const X & XX ){
//...
X X2 = xx; // copy the value
 
// When foo_BAR () changes its reference parameter, X2 is changed, and XX remains unchanged.
Return foo_BAR (X2); // OK
}

3. We can declare reference parameters of any built-in data type.

For example, if a programmer wants to modify the pointer itself rather than the object referenced by the pointer, he can declare a parameter, which is a pointer reference. For example, the following is a function that exchanges two pointers.

 
Void ptrswap (int * & V1, int * & V2) {int * TMP = V2; v2 = V1; V1 = TMP ;}

The following statement
Int * & V1; // actually gets an alias for the pointer, so that you can change the pointer through the alias
Read from the right to the left. V1 is a reference that references a pointer pointing to an int object.

Use the main () function to manipulate the rswap () function. We can modify it as follows:CodeTo exchange two pointer values:

# Include <iostream> void ptrswap (int * & V1, int * & V2); int main () {int I = 10; Int J = 20; int * Pi = & I; int * PJ = & J; cout <"before ptrswap (): \ TPI:" <* pI <"\ TPJ: "<* pj <Endl; // The parameter is the alias of the pointer (that is, the pointer is referenced, then the passed real parameter is the pointer itself, and the principle is the same as that of passing common variables) ptrswap (PI, PJ); cout <"after ptrswap (): \ TPI:" <* pI <"\ TPJ:" <* pj <Endl; return 0 ;}

Compile and run the program to generate the following output:
Before ptrswap (): Pi: 10 PJ: 20
After ptrswap (): Pi: 20 PJ: 10

Iv. Reference parameters or pointer Parameters

Both of these parameters can change the value of the real parameter or effectively transmit large class objects. How can we determine the Parameter definition?

The fundamental difference is that a reference must be initialized to point to an object. Once initialized, it cannot point to other objects. A pointer can point to a series of different objects and can do nothing.

Because the pointer may point to an object or no object, the function cannot safely resolve a pointer (dereference) before determining whether the pointer actually points to a valid object. For example:
Class X;
Void manip (x * px)
{
// Make sure that the pointer is not 0 before resolving the reference
If (PX! = 0)
 
// Unreference pointer
}

On the other hand, for reference parameters, the function does not need to point to an object. The reference must point to an object, even if we do not want this, for example:
Class type {};
Void operate (const type & P1, const type & p2 );
Int main (){
Type obj1;
// Set obj1 to a value
// Error: the real parameter of the referenced parameter cannot be 0
Type obj2 = operate (obj1, 0 );
}

If a parameter may point to different objects in a function, or this parameter may not point to any object, you must use the pointer parameter.

 

An important usage of referenced parameters is that it allows us to effectively implement overload operators while ensuring the directionality of usage.

The following uses the addition and overload operators of matrix objects as an example:

Matrix // addition returns a matrix object
Operator + (// The Name Of The overload Operator
Matrix M1, // type of the operator's left operand
Matrix m2 // type of the right operand of the operator
)
{
Matrix result;
// Do the computation in result
Return result;
}

It can be used as follows:

Matrix A, B, C; A = B + C; A + B + C;

But operator + is passed by value, which is less efficient. If we change it to the pointer parameter:

Matrix Operator + (matrix * m1, matrix * m2)

{
Matrix result;
 
// Calculate in result
Return result;
}

Although efficiency is achieved, such code will appear in use: A = & B + & C and & (& A + & B) + & C; obviously not friendly.

The following is a revised version of the overloaded addition operator of the matrix class.
// Use the new implementation of referenced Parameters
Matrix Operator + (const Matrix & M1, const Matrix & m2)
{
Matrix result;
// Calculate in result
Return result;
}
This implementation supports addition of matrix objects in the following forms
A + B + C

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.