C ++ chapter 2 (data type) iii

Source: Internet
Author: User

Reference Type
Reference is also called an alias (alias ). It can be used as another name of an object. through reference, we can indirectly manipulate objects. the usage is similar to a pointer, but the pointer syntax is not required. in actual programs, references are mainly used as form parameters of functions-class objects are usually passed to a function. this feature is mainly used to pass a class reference in a function. For details, see copy constructor of the class.
Referencing is the alias of the original object. The referencing operation is to operate on the original object itself. Just like a person called Zhu Jun, the nickname is sanmao. To let Xiao Mao do something is to let Zhu Jun do something. the referenced address is the address of the variable it represents.

Reference Application

1. Reference as a parameter

An important role of reference is as a function parameter. In the previous C language, function parameter transfer was a value transfer. If a large piece of data is used as a parameter transfer, a pointer is often used, because this avoids the whole piece of data from being pushed to the stack, it can improve program efficiency. But now (in C ++), another option that is equally efficient (which is required in some special cases) is reference.

# Include <iostream>

Using namespace STD;

Int main ()
{
Int A = 10;
Int & aworkflow =;

Cout <& A <"" <& aworkflow <Endl;

Return 0;
}

The results of & A and & aworkflow are the same.

[Example 2]
Void swap (Int & A, Int & B)
{
Int nchange =;
A = B;
B = nchange;
}
Int main ()
{
Int A = 2;
Int B = 3;
Swap (a, B); // at this time, A and B have been switched over.
Cout <A <; <B <Endl;
}

As shown in [Example 2:

(1) passing a reference to a function has the same effect as passing a pointer. In this case, the parameter of the called function becomes an actual parameter variable or an alias of the object in the original main function, therefore, the operations on the parameters in the called function are the operations on the corresponding target object (in the main function.

(2) using the reference parameter to pass the function does not generate a copy of the real parameter in the memory, it is directly to operate on the real parameter; while using the general variable to pass the function parameter, when a function call occurs, you need to allocate storage units to the parameters. The parameters are copies of the real variables. if the object is passed, the copy constructor will also be called. Therefore, when the data transmitted by a parameter is large, it is better to use reference than to transmit a parameter using a common variable.

(3) Although using pointers as function parameters can achieve the same effect as using references, in the called function, storage units must be allocated to the parameters, the "* pointer variable name" format must be used repeatedly for calculation, which can easily lead to errors and the program reading is poor. On the other hand, at the call point of the main function, the variable address must be used as the real parameter. References are easier to use and clearer.

If you want to use references to improve program efficiency and protect the data transmitted to the function from being changed in the function, you should use regular references.

2. Frequent reference

Common Reference declaration method: const type identifier & reference name = target variable name;

The reference declared in this way cannot be modified by reference to the value of the target variable, so that the referenced target becomes const, achieving the security of reference.

[Example 3 ]:

Int;
Const Int & RA =;
Ra = 1; // Error
A = 1; // correct

This is not just to make the code more robust, but also some other needs.

[Example 4]: assume that the following function declaration is available:

String Foo ();
Void bar (string & S );

The following expression is invalid:

Bar (FOO ());
Bar ("Hello World ");

The reason is that both the Foo () and "Hello World" strings generate a temporary object. In C ++, these temporary objects are of the const type. Therefore, the above expression tries to convert a const type object to a non-const type, which is invalid.

The referenced parameter should be defined as const if it can be defined as Const.

3. Reference as return value

To return a function value by reference, the function must be defined in the following format:

Type identifier & function name (parameter list and type description)
{Function body}

Note:

(1) to reference the returned function value, you must add &

(2) The biggest benefit of returning a function value with a reference is that a copy of the returned value is not generated in the memory.

[Example 5] The following program defines a common function fn1 (which returns the function value using the return value method), and another function FN2, which returns the function value by reference.

# Include <iostream. h>
Float temp; // defines the global variable temp.
Float fn1 (float R); // declare the function fn1
Float & FN2 (float R); // declare the function FN2
Float fn1 (float R) // defines the function fn1, which returns the function value in the return value method.
{
Temp = (float) (R * r * 3.14 );
Return temp;
}
Float & FN2 (float R) // defines the function FN2, which returns the function value in reference mode.
{
Temp = (float) (R * r * 3.14 );
Return temp;
}
Void main () // Main Function
{
Float a = fn1 (10.0); // in 1st cases, the system generates a copy of the data to be returned (that is, a temporary variable)
Float & B = fn1 (10.0); // errors may occur in 2nd cases (different C ++ systems have different rules)
// A reference to a temporary or local variable cannot be returned from the called Function
Float c = FN2 (10.0); // in 3rd cases, the system does not generate a copy of the returned value
// A reference to a global variable can be returned from the called function.
Float & D = FN2 (10.0); // in 4th cases, the system does not generate a copy of the returned value
// A reference to a global variable can be returned from the called function.
Cout <A <C <D;
}

The reference must follow the following rules as the return value:

(1) References to local variables cannot be returned. For details, refer to item 31 of Objective C ++ [1. The main reason is that local variables will be destroyed after the function returns, so the returned reference becomes a reference of "no finger", and the program enters the unknown state.

(2) You cannot return a reference to the memory allocated by the new function. For details, refer to item 31 of Objective C ++ [1. Although there is no passive destruction of local variables, this situation (returning a reference to the memory allocated by the new function) faces other embarrassing situations. For example, if a reference returned by a function only appears as a temporary variable and is not assigned to an actual variable, the space pointed to by the reference (allocated by new) cannot be released, cause memory leak.

(3) You can return a reference to a class member, but it is best to use Const. This principle can be referred to item 30 of Objective C ++ [1. The main reason is that when an object attribute is associated with a business rule, its value assignment is often related to some other attributes or the state of the object, therefore, it is necessary to encapsulate the value assignment operation in a business rule. If other objects can obtain the non-constant reference (or pointer) of this attribute, a simple value assignment to this attribute will damage the integrity of business rules.

(4) References and some Operator Overloading:

Stream operators <and>, which are often used consecutively, for example, cout <"hello" <Endl; therefore, the return value of these two operators should be a stream reference that still supports these two operators. Other optional solutions include returning a stream object and returning a stream object pointer. However, for a returned Stream object, the program must re-(copy) to construct a new stream object. That is to say, two consecutive <operators are actually for different objects! This is unacceptable. If a stream pointer is returned, the <operator cannot be used consecutively. Therefore, returning a stream object reference is the only choice. This unique choice is critical. It illustrates the importance of reference and is irreplaceable. Maybe this is why the concept is introduced in C ++. Value assignment operator =. This operator can be used continuously like a stream operator, for example, x = J = 10; or (x = 10) = 100; the return value of the value assignment operator must be a left value, so that the value can be assigned. Therefore, it is referenced as the only return value choice of this operator.

[Example 6] Return the referenced function value as the left value of the value assignment expression.

# Include <iostream. h>
Int & put (int n );
Int Vals [10];
Int error =-1;
Void main ()
{
Put (0) = 10; // use the put (0) function value as the left value, equivalent to Vals [0] = 10;
Put (9) = 20; // use the put (9) function value as the left value, which is equivalent to Vals [9] = 10;
Cout <Vals [0];
Cout <Vals [9];
}
Int & put (int n)
{
If (n> = 0 & n <= 9) return Vals [N];
Else {cout <"subscript error"; Return Error ;}
}

(5) among other operators, the reference: +-*/four Arithmetic Operators cannot be returned. They cannot return references. The Objective C ++ [1] item23 discusses this issue in detail. The main reason is that these four operators do not have side effect. Therefore, they must construct an object as the return value. Optional solutions include: returning an object and returning a reference to a local variable, returns the reference of a newly assigned object and a static object reference. According to the preceding three rules that reference the returned value, both the 2nd and 3 schemes are rejected. Static object reference is caused by errors because (a + B) = (C + D) is always true. Therefore, only one object is returned.

4. References and Polymorphism

References are another method that can produce polymorphism effects except pointers. This means that a base class reference can point to its derived class instance.

[Example 7 ]:

Class;
Class B: Public {......};
B;
A & ref = B; // use a derived class object to initialize a reference to a base class Object

Ref can only be used to access the members inherited from the base class in a derived class object. It is a base class reference pointing to a derived class. If a virtual function is defined in Class A, and this virtual function is rewritten in Class B, a multi-state effect can be generated through ref.

Reference Summary

Another problem is that the definition must be initialized when being referenced, because it is a code, and it must represent something when it is created, otherwise its existence will be meaningless.
Int ivals = 1024;
// OK: refval is a reference pointing to ival.
Int & refval = ival;
// The error reference must be initialized to point to an object.
Int & refval2;

(1) In reference use, it is meaningless to simply give an alias to a variable. The purpose of reference is mainly used in function parameter transfer, solve the problem of poor transmission efficiency and space of large data or objects.

(2) passing function parameters by reference can ensure that no copies are generated during parameter transfer and improve the transfer efficiency. The use of const ensures the security of reference transmission.

(3) The difference between a reference and a pointer is that after a pointer variable points to an object, it indirectly operates on the variable it points. When pointers are used in a program, the program has poor readability. The reference itself is the alias of the target variable, and the reference operation is the operation of the target variable.

(4) When to use the reference. Stream operators <and>, return values of the value assignment operator =, parameters of the copy constructor, parameters of the value assignment operator =, and references are recommended in other cases.

Boolean Type
A boolean object can be assigned a literal value of true or false. // True or false is the key word of C ++.
When an expression requires a numeric value, both the Boolean object (such as found) and Boolean text are implicitly upgraded to int: false to 0, and true to 1.
Bool found = false;
Int occurrence_count = 0;
While (/* condition omitted */)
{
Found = look_for (/* content omitted */);
// The value of found is increased to 0 or 1.
Occurrence_count + = found;
Just as the text "false" and "true" can be automatically converted to Integers 0 and 1, if necessary, values and pointers can also be implicitly converted to boolean values. 0 or a null pointer is converted to false, so all other functions are converted to true.
// Return the number of occurrences
Extern int find (const string &);
Bool found = false;
If (found = find ("Rosebud "))
// OK: Found = true
// If the pointer to the returned item is found
Extern int * Find (INT value );
If (found = find (1024 ))
// OK: Found = true
Constant
# Macro constant defined by define: This is global, but the value is replaced.
Const modifier: const can replace # define macro definition, which can describe constants, and can modify variables, parameters, return values, and function bodies, but it is an object constant in the class.
The const data member cannot be initialized in the class declaration. The following usage is incorrect because the compiler does not know what the size value is when the class object is not created.
Class
{...
Const int size = 100; // error, attempted to initialize the const data member in the class declaration
Int array [size]; // error, unknown size
};
The const data member initialization can only be performed in the initialization table of the class constructor, for example
Class
{...
A (INT size); // Constructor
Const int size;
};
A: A (INT size): size (size) // initialization table of the constructor
{
...
}
A A (100); // the size of object A is 100
A B (200); // the size of object B is 200

How can we create constants that are constant throughout the class? Do not count on the const data member. Use the class
. For example
Class
{...
Enum {size1 = 100, size2 = 200}; // enumerated constant
Int array1 [size1];
Int array2 [size2];
};
Enumeration)
When writing a program, we often need to define a set of class-related attributes. // Attributes related to objects can be described using Const.
For example, a file class includes read, write, and append
Const int input = 1;
Const int output = 2;
Const int append = 3;
One disadvantage of this method is that when we pass the limit to a parameter, the value can only be one of input, output, and append.
Enumeration provides an alternative method, which not only defines Integer constants, but also forms a set, for example:
Enum open_modes {input = 1, output, append };
Input, output, and append are enumeration members. They represent the complete set of variables that can be used to initialize and assign values to open_modes types.
The enumerated type can be a constant in the entire class, for example
Class
{...
Enum {size1 = 100, size2 = 200}; // enumerated constant
Int array1 [size1];
Int array2 [size2];
};
Enumerated constants do not occupy the storage space of objects. They are fully evaluated during compilation. The disadvantage of an enumerated constant is that its implicit data type is an integer, its maximum value is limited, and it cannot represent a floating point number (such as Pi = 3.14159)

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.