Chapter 10 Test

xiaoxiao2021-03-06  18

Chapter 10 Test

This chapter describes the expression of C , and the expression is operator and operand sequence for one or more of the following purposes:

* Calculate a value from the operand

* Design objects or functions

* Generate "side effects" (side effects is any action for non-expressions, for example, modify the value of an object).

In C , the operator can be overloaded and their meaning can be defined by the user, but their priority and the number of operands cannot be modified. This chapter describes the grammatical and semantics of the instead of overloaded operators provided in the language, including the following topics:

* Type of expression

* Semantics of expressions

* Model conversion

(For more information on the overloaded operator, see Chapter 12 "Operator" in "Overload"). Note: The internal type operator cannot be overloaded, and their behavior is pre-defined.

Expression type

C expressions are divided into the following categories:

* Basic expressions, these are the basis for all other expressions.

* Suffix expression, these are basic expressions followed by an operator, such as an array subscript, or a suffix increase 1 operator.

* Expression consisting of an unicamed operator, the single operator can only function one operand in the expression.

* Expression composed of binocular operators, binocular operators act on two operands in the expression.

* Expressions with conditional operators, the conditional operator is a three-mean operator, only this operator belt three operands in the C language.

* Constant expression, constant expression is constructed entirely of constant data.

* Expression with explicit type conversion, explicit type conversion or "styling conversion" can be used in the expression.

* Expressions with member pointer operators.

* Modeling conversion, type security "Model Conversion" can be used in the expression.

* Run type information indicating the type of object during execution.

Basic expression

Basic expressions are the basis for constructing more complex expressions. They are text, name and range resolution (: :)

Limited name.

grammar

Basic expression:

Writing

THIS

:: identifier

:: Operator function name

:: Limited name

(expression)

name

The text is a constant basic expression that depends on the form of its description, and all information about the explanation will be "text" in Chapter 1 "Specification" in Chapter 1.

The THIS keyword is a class object pointer, which can be used in the non-static member function, and the instance of the class that is called the class is called, the keyword cannot be used outside the class member function.

The THIS pointer is the type * const (where Type is a class name), which does not modify the THIS pointer. The following example gives a member function description and this type:

Class Example {public: void func (); // * const this void func () const; // const * const this void func () volatile; // volatile * const this}

See "THIS pointer type" in Chapter 8, "Type" in Chapter 8, "Type" in Chapter 8, "Type" in the THIS pointer.

Range resolution operators (: :) followed by an identifier, operator function name, or qualified name constitutes a basic expression. This type of expression is specified by an identifier, an operator function name, or a name of the name. If the name value of the description is 1 (1-value), it is also a value of 1 (1-Value). The range resolution operator allows you to indicate a global name, even if the name is hidden within the current range. See Chapter 2, "Scope" in Chapter 2, "Basic Concept" in the example of how to use the scope resolution operator.

Expression contained in parentheses is a basic expression that is identical to the expression that is enclosed in parentheses. If the expression of the non-parentheses enclosed is the L value, it is also a l value.

name

In the syntax of the C basic expression, a name is a basic expression that can only appear after the member selection operator (. Or ->) and name a member.

grammar

name:

Identifier

Operator function name

Conversion function name

~ Class name

Limited name

Any identifier that has been illustrated is a name.

An operator function name is a name that is as follows:

Operator operator name (parameter 1 [, parameter 2]);

For more information on operator function name, see "Overloaded Operators" in Chapter 12 "Overload". A conversion function name is a description as the following form:

Operator Type Name ()

Note: When you explain a conversion function, you can use a derived type name such as a CHAR alternate type name. The conversion function provides the transition to the user-defined type and from the user-defined type. For more information on the conversion provided by users, see "Conversion Functions" in Chapter 11 "Special Member Functions".

Illustrated as the name of the class name is "destructor" as a class type object, which performs clearance operations in an end place of an object survival. See Chapter 11, "Destructor" in Chapter 11, "Destructive Functions" in Chapter 11.

Limited name

grammar

Limited name:

Limited class name :: Name

If a qualified class name is followed by the scope resolution operator (: :), then the member name of the base class of that class or that class, the range resolution operator is considered a limited name, a limited name and a member The same type, and the result of the limited name expression is a member. If the member is a l value, the qualified name is also the l value. See "Type Indicators" in Chapter 6, "Class Name" in Chapter 6, "Classified" in Chapter 6, "Class Name" in Chapter 6, "Class".

A class name part of a qualified class name can be hidden by a reinterpretation of the same name in the current or surrounding range, and the class name can still be found and used. See "Range" in Chapter 2, "Basic Concept" for how to use a qualified class name to access a hidden class name.

Note: Class Name :: Class Name and Class Name :: ~ Class constructor in the form of class name The same class name must refer to the same class name.

With more than one qualified name, as shown below, a member of a nested class is specified:

Class Name :: Class Name :: Name

Suffix expression

The suffix expression constitutes a basic expression or a suffix operator followed by a basic expression. The suffix operand is listed in Table 4.1.

Table 4.1 Suffix operator

Operator Name Operator Symbol Subcommitter [] Function Call Operator () Explicit Type Conversion Operator Type Type-Name () Member Select Operator. Or -> Respected 1 Operator Refix 1 Operation symbol--

grammar

Suffix expression:

Basic expression

Suffix expression [expression]

Suffix Expression (Expression Table OPT)

Simple type name (expression table OPT)

Suffix expression. Name

Suffix expression -> name

Suffix expression

Suffix expression -

Expression table:

Assignment expression

Expression table, assignment expression

Subscript operator

A suffix expression is followed by the subscript operator [], used to specify an array index. One of the expressions must be a pointer or an array type, that is, must have been described as Type * or Type []. Other expressions must be an integer type (including enumeration type). In the usual usage, the expression in square brackets is one of the integer, but there is no strict requirement, considering the following example:

MyType M [10]; // Describes an array of user-defined types

Mytype n1 = m [2]; // Select the third element of array

MyType N2 = 2 [M]; // Select the third element of the array

In the previous example, the expression M [2] is identical to 2 [M]. Although m is not an integer type, the effect is the same. M [2] and 2 [M] are equal because the result of the subscript expression E1 [E2] is given by * (E2) (E1))).

The address generated by the expression is not an E2 byte of the distance address E1, but the address is positioned to generate the next object in the array E2, for example:

Double adb1 [2];

The addresses of ADB [0] and ADB [1] are 8 bytes, namely the dimensions of objects of a Double type, which determined the size of the object type to be automated by the C language, and at this chapter "Additional The operator is defined in which addition and subtraction of the pointer type operand is also discussed.

Positive and negative

The first element of the array is element 0, and the range of C arrays is from Array [0] to Array [Size -1], but C supports positive and negative subscripts. Negative subscripts must fall within the array boundary or result is unpredictable. The following example illustrates this concept:

#include void main () {int inumbrarray [1024]; int * inumberline = & inumbrarray [512]; cout << inumbrarray [-256] << "/ n"; // unpredictable COUT << Inumberline [-256] << "/ n"; // Viable} The negative date in InumberRay may generate an operation error because it produces an address of 256 bytes lower than the original array. Inumberline objects are initialized to InumberRay, so that it can use positive group indexes to use negative group indexes. Array subscript errors do not generate compilation errors, but they produce unpredictable results.

The subscript operator can be interchangeable, so as long as the subscript operator is not overloaded, the expression array [index] and index [array] are considered equal. (See "Optical Operators" in Chapter 12 "Overload"). The first format is the most common encoding method, but both.

Function call operator

A suffix expression is followed by a function call operator (), then specifies a function call, the parameter of the function call operator is 0 or more expressions, and the actual parameters of the function are separated by commas.

The suffix expression must be one of the following types: l Function Return Type T, one description example is: T FUNC (INT i) L function Returns the pointer of Type T, one description example is:

T (* func) (INT i)

* Function Returns the reference to the type T, one instruction example is:

T (& func) (INT i)

* Member pointer function Indirect reference returns Type T, function call example is:

(POBJECT -> * PMF) ();

(Object. * PMF) ();

Formal parameters and actual parameters

The calling program delivers information to the called function in the "actual parameters", and the modified function uses the corresponding "formal parameters" access information.

When a function is called, perform the following tasks:

* All actual parameters (provided by the caller) are evaluated, and these variables are not implicitted when they are evaluated, but all variables are evaluated before entering the function, and all side effects are completed.

* Each formal parameter is initialized in its expression table (a formal parameter is a parameter in the function header, and is used in the function of the function), and the conversion is completed by initialization, ie standard And user-defined conversions are executed to convert the actual parameters to the correct type. The execution of the initialization is conceptually explained by the following examples:

Void Func (INT i); // Function prototype

...

FUNC (7); // Execute function call

Conceptual initialization before calling is:

INT TEMP_I = 7;

FUNC (TEMP_I);

Note that initialization is executed, it is like the use equal syntax rather than parentheses syntax, and one copy of i is made before passing the value (for more information, see "Initialization" in Chapter 7 Expression "," Conversion "in Chapter 11," Special Member Function "," initialization of special member functions "and" explicit initialization ").

Therefore, if a function prototype (description) calls a long type parameter, if the caller provides an int type actual parameter, the actual parameter is upgraded to the long type (see Chapter 3 "Standard Conversion").

It is an error in providing an actual parameter without a standard or user-defined conversion.

For the actual parameters of class types, formal parameters are initialized by calling class constructor (more information on these special class members, see Chapter 11 "Constructor") in Chapter 11.

* Function call is executed.

The following block illustrates a function call:

Void fanc (long param1, double param2); void main () {INT i, j; // calls FUNC FUNC (i, j) with actual parameters I and J; ...}

// Use the formal parameter param1 and param2 definition FUNC

Void Func (Long Param1, Double Param2)

{

...

}

When the FUNC is called from the MAIN, the formal parameter PARAM1 is initialized with the I value (using standard conversion to the correct type corresponding to the i-line type), and the formal param2 uses J value (using standard conversion to Double Types) initialization. Treatment of parameter type

Illustrated as a formal parameter of a constant type cannot be changed in a function, and the function can change any variables of any non-const type. However, change the relative function is part, and does not affect the value of the actual parameter, unless the actual parameter is a reference to a non-const type object.

The following functions illustrate some of these concepts:

INT FUNC1 (Const Int I, INT J, CHAR * C) {i = 7; // Error: i is constant j = 1; // can, but J value is lost in return value * c = 'a' j; / / Can: change the value Return I;} Double & Func2 (Double & D, CouSt Char * c)} Double & Func2 (Double & D, CouSt Char * C)} Double & Func2 (Double & D, CouSt Char * C) {D = 14.387; / / Can: Change D of D * C = 'A' in the call function ; // Error: c is a pointer RETURN D to constant objects.

Moderate and default parameters

The function can explain that the case where the specific parameter is specified in the function definition, which is implemented by one of the following two methods: omitting numbers (...) or default.

The ellipsis means that the parameters may be required, but there is no specified number and type in the description. This is usually a bad C programming method because it fails to one of the benefits of C . Different conversions are used to use functions for the omitted number instead of those known and actual parameter types known:

* If the actual parade is a FLOAT type, it is enhanced as the Double type before the function call.

* Any symbolic or unsigned CHAR, SHORT, enumeration type, or bit domain uses integer boosts to be converted to symbolic or unsigned int.

* Any class type parameter passed as a value of a data structure; copy is achieved by a copy constructor (if present) created by binary copy rather than a general call class.

The omitting number, if used, must be described in the final statement. For more information on transmitting variable number parameters, see the discussion of VA_ARG, VA_START, and VA_LIST in the Microsoft Visual C 6.0 Run References in Microsoft Visual C 6.0 References.

The default parameters enable you to specify a value of such a parameter, assume it not provided in the function call. The following code segment gives the working conditions of the default parameters, and see "Default Parameters" in Chapter 7 for more information on specifying the limitations of default parameters.

#include

// Describe a print function print string and a terminator.

Void Print (const char * terminator = "/ n"); void main () {print ("Hello,"); Print ("World!"); Print ("Good Morning", "," PRINT ("sunshine.");

// Define Print

Void Print (Char * String, Char * Terminator) {if (String! = NULL) Cont << string; if (terminator! = null) cout << terminator;

The previous program illustrates a function print, which has two parameters, but the second parameter TERMINATOR has a default "/ n". In main, the beginning of the two calls in the beginning of the default second parameter provides a string of the online termination print, the third call specifies a clear value, and the output of the program is:

Hello,

World!

Good morning, sunsline.

Function call results

A function call evaluation is a R value unless the function is illustrated as a reference type. The value of the referenced function returns the type value of the value, and can be used for the left side of an assignment statement, as shown below:

#include Class Point {public: // Defines the "accessor" function as reference type unsigned & x () {return _x;} unsigned & y () {return _y;} private: unsigned _x; unsigned _y; }; void main () {Point thepoint; thepoint.x () = 7; // Using x () as an L value UNSIGNED Y = thePoint.y (); // Use Y () as a R value // X () and y () as a r value cout << "x =" << "/ n" << "y = << thepoint.y () <<" / n "; } 000000 The previous code defines a class call Point, including private data objects representing the X and Y coordinates, which must be modified and their values ​​are retrieved. This program is just one of several of such a class, using getx and setx or gety and sety functions are another possible design.

Return class type, class type pointer, or class type reference function can be used as the left operator of the member selection operator, so the following code is legal:

Class A: {public: int seta (INT i) {return (i = i);} int GETA () {Return I;} private: int 1;

// Describe three functions

// func1, return type A

// func2, return a pointer to type a

// Func3, a reference to the type A

A func1 ();

A * func2 ();

A & FUNC3 ();

INT IRESULT = FUNC1 (). Geta ();

Func2 () -> seta (3);

Func3 (). seta (7);

The function can be recursively called, and more information about the function description will be used to see "Function Indicators" in Chapter 6, "Indicators" in Chapter 8 and "Members" in Chapter 8. Related materials in the "Program and Connection" in Chapter 2 "Basic Concept".

Member selection operator

A suffix expression is followed by a member selection operator (.) And a name, is another example of a suffix expression. The first operand of the member chooses the operator must have a class or class reference type, and the second operand must identify one member of the class.

The result of the expression is the value of the member, and if the named member value is 1, it is worth 1.

A suffix expression is followed by a member selection operator (->) and a name, is a suffix expression. Members Select the first operand of the operator must have a type of object of a class object (an object of the Class, Struct, or Union type); the second operand must specify a member of that class.

The result of the expression is the value of the member, and if the named member value is 1, it is also a value of 1. -> Operator Indirect reference pointer,,,, ).

When a value is stored by a joint member, no conversion is executed when another member is retrieved. The following procedures store data into object u, but retrieved data as two separate bytes of char types:

#include void main () {strat ch {char b1; char b2;}; union u {structure ch uch; short i;}; u u; ui = 0x6361; // "ac" bit mode Cout << u.uch.b1 << u.uch.b2 << "/ n";

Human suffix 1 and minus 1 operator

C provides prefix and suffix increases 1 and minus 1 operator; this section only describes 1 and minus 1 operator. (For more information, see Chapter 12 "Increase 1 and Reduction 1"). The difference between the two is that in the suffix representation, the operator appears after the suffix expression, and in the prefix representation, the operator appears prior to the expression. The following example gives a suffix increase 1 operator: i uses the suffix increase 1 or "increasing 1" operator ( ) to the operand to increase a single unit of the corresponding type. Similarly, the role of using the suffix reduction 1 or "reducing 1" operator (-) is to reduce the amount of the corresponding type.

For example, use the suffix increase 1 operator in a pointer to an array of LONG type objects, in fact, the internal representation of the pointer is increased 4. This action makes the first pointing to the northern n element point to the (N 1) element.

The operand of the suffix 1 and the suffix 1 operator must be an arithmetic or pointer type can be modified (non-const) l value, the suffix increase 1 or the suffix reduction 1 expression is the result of the suffix before using the 1 operator The value of the formula, the same type of result is the same as the suffix expression, but no longer a l value.

The following code illustrates the suffix increase 1 operator:

IF (var > 0)

* p = * q ;

In this case, the variable var is then incremented by 1. If VAR is positive before adding 1, the next statement is performed. First, the value of the object to which the q is assigned to the object pointing by the P, then, Q and P are incremented by 1. Afterward 1 and then reduce 1, when used for enumeration type, generate an integer value. Therefore, the following code is illegal:

ENUM day {Sunday = 1, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday}; void main () {days Today = Tuesday; days savetoday; savetoday = Today ; // error}

The purpose of this code is to save Today's gable numbers, then move to the next day, but the result is an incorrect when the Today expression generates an INT that occurs when it is assigned to the enumerated type DAYS.

Expression with single operator

The single operator acts only on an operand in the expression, and the single operator is:

* Indirect operator (*)

* Take the address operator (&)

* Single-grade portable operator ( )

* Single load operator (-)

* Logic non-operator (!)

* "1" for the calculation operator (~) L prefixed

1 operator ( ) l prefixed

1 operator (-) L Sizeof operator

* New operator

* Delete operator

These operators have a binding law from right to left.

grammar

Monocular expression:

Suffix expression

single-graphic expression

- single-grade expression

Single Operator Model Conversion Expression

SIZEOF. Monocular expression

SIZEOF (Type Name)

Distribution expression

Revoke allocation expressions

Single Operator: One of the following

* & -! ~

Indirect operator (*)

Single-grade indirect operator (*) "Indirect reference" a pointer, that is, it converts a pointer value to a l value. The operand of indirect operators must be a type of pointer. The result of an indirect expression is the type of pointer type from its derived type. In this context, the use of the operator is different from it as the meaning of the multiplication as a binocular operator.

If the operand points to a function, the result is a function indicator. If it points to a storage location, the result is a 1 l value of the storage location.

If the pointer value is invalid, the result is uncertain. The following table includes some of the most common conditions to make the pointer value

* The pointer is an empty pointer.

* The pointer specifies the address of a partial item and is invisible when referenced.

* Pointer Specifies an address inappropriate to align with the type pointed to by the object

* The pointer specifies an address that is not used by executing.

Take the address operator (&)

Unco-access address operators (&) Take the address of its operand, and take the address calculation to only be used for the following cases:

* Function (although the usage of the function address is not required)

* l value

* Limited name

In both cases listed above, the result of the expression is a pointer type (a R value) that is generated from the operand type. For example, if the operand is a CHAR type, the result of the expression is the CHAR pointer type. Take the address operator is used for Const or Volatile object equal to const type * or volatile type *, where type is the type of source object. The third case will take the address operator to apply on a qualified name. The resulting result depends on whether the defined name specifies a static member. If yes, the result is a pointer to the specified type in the member description; if the member is not static, The result is a pointer to the class member name indicated by the defined class name (more information on the qualified class name, see "Basic Expressions" in front of this chapter). The following code segment is given: how the result is different from whether it is a static result:

Class PTM {Public: INT IVALUE; Static float Fvalue;};

INT PTM :: * Pivalue = & PTM :: ivalue; // Viable: Non-static

Float PTM :: * PfValue = & PTM :: Fvalue; // Error: Static

Float * spfvalue = & ptm :: fvalue; //

In this case, the expression & ptm :: fValue generates a float * type instead of the float ptm :: * type, because Fvalue is a static member.

An address of a heavy-duty function is clearly known to which version of the function can be obtained. For information on how to get the address of a specific overloaded function, see "Overloaded" in "Overloaded" in Chapter 12.

Use the address operator to use the operator on an object to a reference type

Out of the same result. The following procedure illustrates this concept:

#include void main () {double D; // Defines an object Double & Rd = D of the Double type; / / Defines an address of the object and the address of the object and an object reference address IF (& D) == & rd) cout << "& d Equals & rd" << "/ n"; Else Cout << "& iS not equal to & rd" << "/ n";}

The output of the program is always: & d Equals & rd.

Single-grade plus operator ( )

The result of the single-grade portable operator ( ) is the value of its operand. The operand of the single-grade portable operator must be an arithmetic type.

Perform an integer increase on the integer operand. The result type is the type of operation of the operand. Thus, expression ch, where CH is a CHAR type, resulting in int type; value is not modified. For information on how to complete, see Chapter 3, "Standard Conversion" in "Standard Conversion".

Single load operator (-)

The single load operator (-) is reversed to its operation. The operand of the single load operator must be an arithmetic type.

The integer increase is performed on the integer operand, and the result type is the type of operand being improved. Relevant promotion is as possible, see Chapter 3, "Standard Conversion" "" Standard Conversion ".

Microsoft Special Office

The execution of the unsigned amount is a negative of the operand from 2N, where n is a bit number of objects that give a sign-unsigned type (Microsoft C runs in the processor of the complement of 2). In other processors, it may vary depending on the counter.

Microsoft End

Logical non-operator (!)

If the operand is a non-0 value, the result of the logical non-operator (!) Is 0; the result is 1 when the operand is 0. The operand must be an arithmetic or pointer type, and the result is an int type.

For an expression E, a single-grade expression! E is equal to the expression (E == 0), unless the overloaded operator is included. The following example illustrates the logical non-operator (!):

IF (! (x

If X is greater than or equal to Y, the result of the expression is 1 (true); if X is smaller than y, the result is 0 (fake).

The single-grade arithmetic operation of the pointer is illegal.

"1" and supplementation operators (~)

"1" to make up the operator (~), sometimes referred to as "bit to make up" operators, generate the "1" of the bit bit of its operand, that is, each bit is 1 in the operand The medium is 0; vice versus, each of the operands is 1 in the result. "1" The operand for the operation of the operator must be integer. UNSIGNED SHORT Y = 0xAAA;

Y = ~ y;

In this example, the new value assigned to Y is "1" for the unsigned value 0xAAAA or 0x5555.

The integer increase is performed on the integer operand, and the result type is the type of operand being improved. For more information on how the upgrade is completed, see "Integer improvement" in Chapter 3 "Standard Conversion".

Increase 1 and minus 1 operator ( , -)

Prefix 1 operator ( ), also known as "first increment 1" operator, add 1 on its operand, and the value of this plus 1 is the result of the expression. The operand must be a non-const type L value, the result is the same L value as the operand type.

The prefix is ​​reduced by 1 operator (-), also known as "award 1" operator, similar to the previous increment 1 operator, except that the operand is reduced by 1 and the result is this reduced value.

The prefix and the suffix increase 1 and the 1 operator affect its operand, the key difference is when the value of the expression is increased by 1 or minus 1 (for more information, see the previous "suffix increase 1 and minus 1 operator "). In the prefix form, the increase in 1 or decreases to occur before the value is used for the expression value, so the value of the expression is different from the value of the operand; in the suffix form, the increase of 1 or minus 1 occurs in the bit After the expression is evaluated, the value of the expression is the same as the value of the operand.

The operands of the integer or floating point type are increased or minus the integer value 1. The type of the result is the same as the operand type; the pointer type operand is added 1 or minus 1 or minus 1, and points to 1 pointer The next object, the pointer subtracted 1 point is an object.

This example illustrates a single grade minus 1 operator:

IF (Line [--i]! = '/ n')

Return;

In this case, the variable I is reduced before use as the Line subscript.

Because the increase 1 and the minus 1 operator have side effects, use the expression of 1 or minus 1 operator in the macro to produce unexpected results (more information about macros, see the back "Preprocessor reference" "Mob"). Consider the following example:

#define max (a, b) ((a) <(b))? (b): (a)

...

INT I, J, K;

K = Max ( i, j);

Macro expansion is: k = (( i) <(j))? (J): ( i);

If i is greater than equal to J, it will increase twice.

Note: In many cases, the inline function is better than the macro because they eliminate the side effects described here, and allow language to perform more complete type detection.

Sizeof operator

The SIZEOF operator produces an operand size of the CHAR type size. The result of the SizeOf operator is a size_t type, which is defined in an integer in including file stddef.h. The sizeOf operand can be one of the following:

* A type name. The name must be enclosed with parentheses with a name name.

* An expression. When used in an expression, SIZEOF can be specified or without parentheses, which does not evaluate. When the SizeOf operator is used for the CHAR type object, it is 1;

When the SizeOF operator is used in an array, it is the result of the number of bytes in that array. E.g:

#include void main () {char szhello [] = "Hello, World!"; cout << "The size of the type of" << Szhello << "IS:" << Sizeof (char) << "/ n"; cout << "The length of" << Szhello << "IS:" << sizeof szhello << "/ n";

The program output is:

The size of the type of hello, world! Is: 1

The Length of Hello, World! IS: 14 When the SizeOF operator is used for Class, Struct or UNION type, the result is the byte number of an object of the Class, Struct or UNION type plus the word boundary. Fill bytes. (/ ZP [Compact Structure Member] Compiler Options and Pack Compile Indicates that affects the alignment boundary of the member). The SIZEOF operator never produces 0, even if it is for an empty class.

The SIZEOF operator cannot be used for the following operands

* Function (but sizeof can be applied to function pointers)

* Bit field L Uneascent class l void type

* Incomplete type

* The name of incomplete types enclosed in brackets

When a SizeOF operator is used for a reference, the result is like Sizeof is used for object itself. The SIZEOF operator is often used to calculate the number of elements of an array, using the following form:

Sizeof array / sizeof arrrey [0]

NEW operator

The New operator attempts to dynamically allocate one or more objects of the type name of (at runtime). The NEW operator cannot be used to assign a function, but can be used to assign a function pointer.

grammar

Assign expression:

:: Opt New Location OPT New Type Name New Initializer OPT

:: Opt New Location OPT (Type Name) New Initializer OPT

position:

(Expression table)

New Type Name:

Type Indicator New Configuration OPT

The NEW operator is used to assign objects and object arrays, and the New operator is allocated from a program memory area called "free storage". In C, the free memory area is often indicated as "heap".

When the New is used to assign a single object, it generates a pointer to that object; the result type is a new type name * or type name *; when the New is used to assign a single-dimensional object array, it generates a pointing array The first element of the pointer, the result type is a new type name * or type name *; when the New is used to assign a multi-dimensional object array, it generates a pointer to the first element of the array, and the result type retains the leftmost All sizes outside the array dimension, for example:

NEW FLOAT [10] [25] [10]

Generate type float (*) [25] [10]. Therefore, the following code cannot work because it tries to assign the dimension of the pointer of the type float to a pointer to a Float array:

Float * fp;

FP = New float [10] [25] [10];

The correct expression should be:

FLOAT (* CP) [25] [10]

CP = New float [10] [25] [10];

The definition of CP is allocated with a dimension [25] [10], which assigns a pointer to the FLOAT type array, which does not assign the pointer array. In addition to all dimensions in the leftmost array dimension must be equal to a constant expression; the leftmost array dimension can be equal to any expression of the positive number, when the NEW operator assigns an array, the first dimension The number can be 0, and the New operator returns a unique pointer.

Type indicators cannot include const, volatile, class descriptions, or enumeration descriptions. Therefore, the following expressions are illegal:

Volatile char * vch = new volatile char [20];

The New operator does not assign a reference type because they are not objects.

If there is not enough memory to meet the allocation requirements, the default Operator New returns NULL. You can change this default behavior by writing customized exception handling routines and calling the _SET_NEW_HANDLER Running function with your function name as a parameter. For more details on this recovery mode, see "Operator New Features" in Chapter 11 "Special Member Functions".

Survival of objects allocated with new

The object assigned with the New operator is not destroyed when they exit from the defined range. Because the New operator returns the pointer of the object it assigns, the program must define a pointer with the appropriate range to access those objects. E.g:

Void main () {// Assign a 20-character array using a New operator Char * AnaRray = New Char [20]; for (int i = 0; i <20; i) {// in the loop When it is iterated, the array IF (i == 0) {char * anotherarray = new char [20];} ...} delete annage; / Can: The pointer is also within the scope} Once the pointer Anotherarray is exceeded, the object can no longer be deleted.

Initialize objects with new allocation

Option The New Initializer domain is included in the syntax of the New operator, allows the NEW object to be initialized using the user-defined constructor. See "Initializer" in Chapter 7, "Initializer" on Chapter 7, "Initializer" on the initialization.

The following example shows how to use an initialization expression with a New operator:

#include Class Acct {public: // Defines the default constructor and constructor accept the initial balance activity () {balance = 0.0;} acct (double init_balance) {balance = init_balance;} Double balance; void main () {acct * checking acct = new acct; acct * savingAcct = new acct (34.98); double * howmuch = new double (43.0); ...}

In this case, the object checkingAct uses the New operator allocation, but does not specify the default initialization, therefore, the default constructor ACCT () of the class is called; then assigns the object SavingAct in the same way, but is explicitly initialized 34.98. Since 34.98 is a Double type, the call is initialized by this type of constructor. Finally, non-class type howmuch is initialized to 43.0.

If an object is a class type, and that class has a constructor (as in the previous example), the object can be initialized by the new operator when one of the following conditions is satisfied:

* The parameters provided in the initializer are consistent with those parameters in the constructor.

* There is a default constructor (a constructor that can be invoked without a parameter). Access control and fuzzy control on the constructor of the rule set presented in the "Special Member Function" in Operator New and in accordance with the "Delivery" in Chapter 9 and "Special Member Function" in Chapter 11 "Special Member Function" carried out.

When allocating an array with a New operator, it is not explicitly performed to perform initialization for each element; if it exists, only the default constructor is called. For more information, see "Default Parameters" in Chapter 7, "Degree".

If the memory assignment fails (Operator NEW returns an 0 value), no initialization is performed, which prevents initialization of the non-existing data.

Due to function calls, initialization expressions are not defined in order, and you cannot rely on these expressions before the memory is fully evaluated. If the memory assignment fails, the New operator returns 0, and some expressions in the initializer may not be completely evaluated.

How does New work?

Allocating expressions, including new operators, do three things:

* Locate and retain memory for objects or object to be assigned, when this step is completed, allocate the correct storage unit number, but is not an object.

* Initialize the object, once initialized, there is sufficient information to allocate storage for the object.

* Returns a pointer to the pointer type object derived by new-type-name or type-name, the program uses the pointer to access the newly assigned object

. New operator call function operator new. For any type of array and non-Class, Struct or UNION type objects, global functions :: Operator New is called to assign a memory, and class type objects can define their own Operator New static members on the basis of each class.

When the compiler encounters a new operator to assign a Type type object, it calls type :: "); or if there is no user-defined Operator New is defined, call :: Operator New (Sizeof (Type ))). Therefore, the New operator can assign a correct number of memory for an object. Note: The parameter of Operator New is a size_t type, which is defined in Direct.h, Malloc.h, Memory.h, search.h, stddef.h, stdio.h, stdlib.h, string.h and time.h .

An option in the syntax allows the specification of the location (see the syntax of the New operator). This positional parameter can only be used in the implementation of the Operator New user definition; it allows additional information to operatornew, with location domain expressions such as:

T * TOBJECT = New (0x0040) T;

Translated as: T * TOBJECT = T :: Operator New (SizeOf (T), 0x0040);

The initial purpose of the location is to allow access to the hardware's object to allocate at the user specified.

Note: Although the previous example gives only one parameter in the location domain, how many additional parameters in this manner can be passed to Operator New and is not limited.

Even if the Operator New is defined for a class type, the global operator can also be used in the form of the following example:

T * TOBJECT = :: New TOBJECT:

Range Faith Codes (: :) Force use global new operators.

Delete operator

The Delete operator revokes object assignments created by the New operator. The Delete operator has a result of a Void type, so the value is not returned, and the execution of the delete must be a pointer returned by the New operator.

The object pointer that is not assigned to use DELETE will generate unexpected results, but you can use delete to use a pointer with 0 values. Because NEW always returns 0 in the event of failure, this measures means that the result of deleting a failing New operation is harmless.

grammar

Undo assignment expression:

:: Opt Delete Model Conversion Expression

:: Opt Delete [] Model Conversion Expression

To use the Delete operator to an object will revoke its memory allocation, a program indirectly references a pointer after the object is deleted, and a pointer will generate unexpected results or crash.

If the operand of the Delete operator is a modified l value, its value is undefined after the object is deleted.

The constant object pointer cannot be assigned with the Delete operator.

How does Delete work?

DELETE operator call function operator DELETE, the class type (Class), Struct (Structure), and Union (United)) object, DELETE operator calls the destructor before the memory allocation (if the pointer is not empty) . For non-class type objects, the global DELETE operator is called. For class type objects, the DELETE operator can be defined based on each class. If there is no such definition for a given class, the global operator is called.

Use Delete

There are two grammar variations for the Delete operator: a for a single object, the other is an array of objects. The following code segments give these differences:

Void main () {// Using the New Operator Assign a user-defined object UDObject and Double type object UDTYPE * udobject = new udtype; Double * DOBJECT = New Double; ... // Delete two objects delete udobject DELETE DOBJECT; ... // Use the New operator to assign a user-defined object array udtype (* udarr) in the free storage area [7] = new udtype [5] [7]; ... // Use the array syntax to delete Object array delete [] udarr;}

These two situations produce undefined results: an array of delete uses delete in an object (delete []) and the non-array form using Delete in an array.

Expression with binocular operators

The binocular operator acts on two operands in an expression. Bottom operators are:

Multiplication operator

multiplication(*)

division(/)

Taking mold (%)

Addition operator

Addition ( )

Subtract (-)

Displacement operator

Right shift (>>)

Left movement (<<)

Relationship and equivalent operator

Small than (<)

Big than (>)

Less than or equal (<=)

More than or equal (> =)

Equal (==)

Not equal to (! =)

Bit operator

Bit and (&)

Press or (^)

Bit or (|)

Logic and (&&)

Logic or (||)

Multiplication operator multiplication

The operator has:

* Multiplication (*)

* Division (/)

* Take a mode or "division] (%)

These binocular operators have a binding law from left to right.

grammar

Multiplication expression:

PM expression

Multiplication Expression * PM Expression

Multiplication Expression / PM Expression

Multiplication Expression% PM expression

Multiplication Expression uses an arithmetic type operand, and the model operator (%) has a stricter requirement, that is, its operand must be integer (the remainder of floating point division, using the run function FMOD). Chapter 3 "Arithmetic Conversion" included in "Standard Conversion" is suitable for operands, and the result is the type of conversion.

The multiplication operator generated is the result of the first operand by the second multiplication.

The first operator is generated by the first operator being the result of the second.

The mode operator produces the remainder given by the expression E1- (E1 / E2) * E2, where E1 is the first operand, E2 is the second operand, wherein the two operands are integer.

It is not defined in the division or mode-to-mode expression, and a run error is generated. Therefore, the following expressions produce undefined errors:

I% 0

F / 0.0

If the two operands of the multiplication, division or molding expressions have the same symbol, the result is positive; otherwise, the result is negative, the symbol sum of the mode operation is the implementation of the definition.

Microsoft Special Office

In Microsoft C , the result of the molding expression is always the same as the symbol of the first operand.

Microsoft End

If the division of the two integer calculations is inaccurate, only one operand is negative, the result is the maximum integer (in quantity, no symbol) than the exact value generated by the division. For example, the result of -11 / 3 is -3.66666666, and the result of the integer division is -3.

The relationship between the multiplication operators is given by the following:

(E1 / E2) * E2 E1% E2 == E1

Addition operator

The addition operator is:

* Addition ( )

* Subtract (-)

These binocular operators have a binding law from left to right.

grammar

Adding expression:

Multiplication

Addition expression multiplication expression

Adding Expression - Multiplication Expression

The addition operator uses an arithmetic or pointer type operand. The result of the addition operator ( ) is the operation number and the result of subtraction operators (-) is the difference between operands. If one or two operands are pointers, they must be the pointer of the object, not a pointer to the function.

The number of operators operates is arithmetic, integer or scalar type, which is defined in Table 4.2.

Table 4.2 Types used by the addition operator

Type Meaning Calvary Integer & Floating Point Type Reference to "Arithmetic" Type CHAR and All Sizes INT (long, short) type and enumeration are "integer" type scale type scalar type operands are arithmetic or pointer types Operand

The legal combination of these operators is:

Arithmetic arithmetic

Scalar integer

Integer scalar type

Arithmetic - arithmetic

Scalar type - scalar type

Note: The addition and subtraction is not an equivalent operation.

If the two operands are arithmetic types, the conversions including "arithmetic conversion" in Chapter 3 "Standard Conversion" are applied to operands, and the result is the type of converted.

Pointer type

If an operand in the addition operation is a pointer to an array of objects, the other must be intellectual, and the result is a pointer with the source pointer and points to another array element. The following code segment describes this concept:

Short IntArray [10]; // short type object accounts for two bytes short * PintArray = int Array; for (int i = 0; i <10; i) {* pintarray = i; cout << * PintArray < <"/ n"; pintaRray = PintArray 1;}

Although the integer value is added to PintArray, it does not mean "add 1"; but refers to the next object in the pointer to the array ", and it is just two bytes (or Sizeof) INT). Note: PintArray = PintArray 1 The code is rarely seen in the C program. In order to execute 1, better: PintArray or PintArray = 1. Pointer type subtraction

If the two operands are pointers, the result of subtraction is the difference between the two operands (in array elements). The subtraction expression produces a type of PTRDIFF_T (defined in the standard including file stddef.h) with symbolic integer results.

One operand can be intellectual, which can only be the second operand. The result of the subtraction and the source pointer are the same type, and the value of the subtraction is a pointer to the (N-I) array element, where n is an element indicating by the source pointer, i is an integer value of the second operand.

Displacement operator

The bit shift operator is:

* Right shift (>>)

* Left movement (<<)

These binocular operators have a binding law from left to right.

grammar

Displacement expression:

Addition expression

Displacement expression << addition expression

Displacement expression >> addition expression

The two operands of the shift operator must be integer, and the implementation of the integer improvement is performed in accordance with the rules specified in "Integer" in Chapter 3 "Standard Conversion". The type of result is the same as the left operating type. The value of the right shift expression EL >> E2 is E1 / 2E2; the value of the left shift expression E1 << E2 is E1 * 2E2.

If the right operand of the shift expression is negative or if the right operand is greater than or equal to the number of digits (lifted), the result is undefined.

The left movement operator allows the bit mode of the first operand to move from the number of bits specified by the second operand, and the vacancy fill by the shift operation is 0 filled, which is logical shift, opposite to the cyclic shift. .

The right shift operator makes the bit mode of the first operand moves to the right of the number of bits specified by the second operand. The vacant fill for the unconservation amount shift is 0 fill, the symbol bit is incoming space. If the left operation is a unsigned amount, the shift is a logical shift, otherwise it is an arithmetic shift.

Microsoft Special Office

The right-shifted result of a sign is dependent on the implementation of the definition, although Microsoft C propagates the most important bit to fill the vacancy, but does not guarantee that other implementations do.

Microsoft End

Relationship and equality operator

The relationship is specified in the equal, inequality, or relationship value of its operand, and the relational operator is shown in Table 4.3.

Table 4.3 Relationships and equality operators

Operator meaning == equal to! = Not equal to greater than <= less than or equal to> = greater than or equal

Relational operator

The two-dimensional relational operator specifies the following relationships:

* Less than

* more than the

* Less than or equal

* greater or equal to

grammar

Relationship expression:

Displacement expression

Relationship expression

Relationship expression> Displacement expression

Relational expression <= shift expression

Relational expression <= shift expression

The relationship operator has a combination of the left to right. The two operands of the relationship operator must be an arithmetic or pointer type, which produces an int type value. If the relationship is related in the expression, the value returned is 0; otherwise 1. Consider the following code, which illustrates several relationship expressions:

#include void main () {cout << "The true expression 3> 2 yields:" << (3> 2) << "/ n"; cout << "The false expression 20 <10 yields : "<< (20 <10) <<" / n "; cout <<" The Expression 10 <20 yields: "<< (10 <20 <5) <<" / n ";

The output of this program is:

The True Expression 3> 2 Yields: 1THE FALSE Expression 20 <10 Yields: 0

The Expression 10 <20 <5 Yields: 1

The expression in the foregoing example must be included in parentheses because the insertion operator (<<) is higher than the relationship operator. Therefore, the first expression without parentheses will be equal to:

(COUT << "The True Expression 3> 2 yields:" << 3) <(2 << "/ n");

Note that the third expression is equal to 1, because the relational operator is from left to right, the explicit packet of the expression 10 <20 <5 is:

(10 <20) <5

Therefore, the test is executed:

1 <5

The result is 1 (or true).

Chapter 3 "Arithmetic Conversion" in "Standard Conversion" includes common arithmetic conversion to the arithmetic type of operands.

Compare pointers with relational operators

When two pointers of the same type of objects are compared, the result is specified by the object location of the program address space. The pointer can also be compared to a constant expression equal to 0 or VOID * type pointer. If the pointer is compared to the Void * type pointer, another pointer is implicitly converted to a VOID * type. Then compare.

Different types of two pointers cannot be compared, unless:

* A type of class is derived from another type.

* At least one pointer is explicitly converted (forced) to the VOID * type (another pointer is implicitly converted to a VOID * type).

Two pointer points to the same type of object assurance comparison result is equal. If the two nonstatic member pointers of an object are compared, use the following rules:

* If the class type is not a combination, and if the two members are not softened by an access indicator such as public, protected and privately separated, the members pointers described later will be larger than the pointers of the previously described members (related to access indicators) See the grammatical part of "Access Specifier" in Chapter 10, "Members Access Control").

* If the two members are separated by the access indicator, the result is uncertain.

* If the class type is a combination, the pointer to which the different data in this franchise is equal.

If the two pointers point to elements in the same array beyond the tail of the array, the pointers with higher smaller objects are higher. The comparison of the pointer ensures effective when the pointer points to the same array object or pointing to a certain location exceeding the array boundary.

Equality operator

Both the other operators compare their operands are strict or equal.

Grammatical phase-equivalent expressions:

Relational expression

Equal expressions == Relationship expression

Equal expressions! = Relational expression

The equal operator: equal to (==) and does not equal (! =) Lower than the relationship operator priority, but their behavior is similar.

If the number of two operands have the same value of the equal value (==) return true value; otherwise returns the false value. The unequal operator (! =) Returns the true value when the two operands have different values, otherwise returns the false value.

The equal operator can compare two similar type member pointers. In this comparison, the transformation of the executive member pointer is discussed in "Member Pointer Conversion" in Chapter 3 "Standard Conversion". Member pointers can also be equal to

0 constant expressions are compared.

Bit operator

The bit operator is:

* Bit and (& &)

* Position or (^)

* Bit or (|)

These operators return a bit combination of their operands.

Bit and operator

Bit and Operators (&) Returns the bits and results of the two operands. The bit in the left and right operands is 1 in the result in the result, and the bit of 0 in any operands is 0 in the result.

grammar

And expressions:

Relational expression

Equally expressions with expressions

Both operands of bit and operators must be integrated, including common arithmetic conversion in "Arithmetic Conversion" in Chapter 3, "Standard Conversion" is used to operate on the number of operands.

Pressibility or operator

The component or operator (^) returns the bitmap or result of the two operands. All bits of 1 in the left and right operands but are not all bits, appearing in the result (1 or 0) of the same value in the two operands (1 or 0) in the result is 0.

grammar

Tone or expressions:

Expression

Tone or expressions ^ and expressions

The two operands of the inner or operator must be intellectual, including common arithmetic conversion of "arithmetic conversion" in Chapter 3 "Standard Conversion" is used to operate on the number of operands.

Bit or operator

The bit or operator returns two operand bit or results, all bits 1 in the left or right operand are 1 in the result, and the bit in the two operands is 0 in the result. 0. grammar

Or expression:

Tone or expressions

Or expression | alone or expression

Both operands of the bit or operator must be intellectual, including common arithmetic conversion of "arithmetic conversion" in Chapter 3 "Standard Conversion" is used to operate on operands.

Logical Operators

Logic operators: Logic and (&&) logic or (|) are used to combine multiple conditions formed using relationships or equally expressions.

Logic and operator

Logic and operators return to the integer value when both operands are not 0; otherwise returns 0. Logic with the binding law from left to right.

grammar

Logic and expression:

Expression

Logic and Expression && or Expressions

Logic and operators do not require the same type, but they must be integer or pointer types, and operands are usually related or equal expressions.

The first operand is completely evaluated before continuing to calculate the value of the logic and the expression, and all side effects are also completed.

The second operand is only calculated when the first operand is evaluated as true (non-0), which removes the second operand in the logic and expression of unnecessary Ask, you can use this short-circuit computing to prevent indirect references for empty pointers, as shown in the following examples:

Char * pch = 0

... (PCH) && (* pch = 'a');

If the PCH is empty (0), the right end of the expression will never be evaluated, so the assignment of the null pointer is impossible.

Logic or operator

The logic or operator returns an integer value 1 when any one of the operands is non-0; otherwise it returns 0, logic, or has a bond from left to right.

grammar

Logic or expression

: Logic and Expressions

Logic or expression || logic and expression

The logical or operator operand does not require the same type, but must be an integer or pointer type, the operand is usually a relationship or equal expression.

The first operand is completely evaluated before proceeding to the logic or expression, and all side effects are completed.

The second operand is only calculated when the first operand is evaluated (0), which is calculated, which removes the second operand in the logic or expression of it is unnecessary. value.

Printf ("% d", (x == W || x == y || x == z));

In this example, if the X is equal to any value in W, Y or Z, the second variable of the PRINTF function is true, and the value is printed. Otherwise, it evaluates the false, and the printed value is 0, as long as there is a condition value to be true, the value is terminated.

Assignment operator

The assignment operator stores a value in the object specified by the left operating. There are two assignment operations: "Simple Assignment" is to store the value of the second operand to the object specified by the first operand; "compound assignment" is performed before the storage result is previously displayed. operating. All assignment operators outside of Table 4.4 are compound assignment operators in addition to the = operator.

Table 4.4 Assignment Operator

Operator meaning = store the value of the second operands into the object specified by the first operand ("Simple Assignment") * = Put ​​the first operation value by the second operation value, deposit the result into the first One operand specified object / = divide the first operating value with the second operation value, store the result in the first operand specified in the object,% = first operand divided by the second operation The number of analog numbers, store the results in the object specified by the first operand = In the value of the value of the second operand, save the result into the object specified by the first operand. Medium - = The value of the second operand is subtracted from the first operation value, and the result is stored in the first operand specified << = to move the value of the first operand to the left. The number specified by the value, store the result in the object specified by the first operand >> = The number of digits specified by the value of the first operand number, and store the result into the first The object specified by an operand & = gets the results of the first and second operands, and store the result in the object specified by the first operand ^ = acquisition first and second operands As a result, save the results in the object specified by the first operand | = Get the first and second operands, the result is stored in the object specified by the first operand.

grammar

Assignment expression:

Conditional expression

Single-eye expression assignment operator assignment expression

Assignment Operator: One of the following

= * = / =% = = - = << = >> = & = ^ = | = The result of the assignment operator

The assignment operator returns the value after assigning the value specified by the left operating. The type is the type of left operation. The result of assignment expressions is always a l value. These operators have a combined law from right to left. The left operation must be a modified L value.

Note: In ANSI C, the result of assignment expressions is not a L value, so the legal expression of C (A = B) = C is illegal in C.

Simple assignment

Simple assignment operator (=) stores the value of the second operands into the object specified by the first operand. If both objects are arithmetic types, the right operand is converted to the left operation before the value stored.

. Const and Volatile type objects can assign a l value of the Volatile or neither Const and the Volatile type.

The assignment of the class type (Struct, Union and Class type) object is executed by the function named operator =. The default behavior of this operator function is to perform a bit copy; however, this behavior can be modified using an operator overloaded (see "overloaded operators" in Chapter 12 for more information). Any object from a given base class is a class of classes that can be assigned to an object of the base class. Otherwise, it will not be, since there is implicit conversion from the derived class to the base class, but from the base class to the derived class. For example: #include

Class abase {public: abase () {cout << "constructing abase / n";}}; - Class ADERIVED: PUBLIC ABASE {public: aderived () {cout << "constructing aderived / n";}}; void Main () {abase abase; aderived aderived; abase = aderived; // Viable aderived = ABASE; // Error}

The assignment of the reference type is like assigning the objects that are referenced by the reference point.

. Different types of type objects, assignment and initialization. In order to illustrate how different assignments and initialization, consider the following code:

UserType1 a;

UserType2 b = a;

The above code gives an initializer that calls the constructor for the userType1, which is a parameter with a useertype1 type. Give code:

UserType1 a

Usertype2 b;

B = a;

Assignment statement:

B = a; can have one of the following:

* Call the function operator =, the operator provided for the useertype2 = is provided with a useertype1 parameter.

* Call the explicit conversion function usePertype1 :: Operator Usertype2, if this function exists.

* Call a constructor usepe2 :: useertype2, if such constructor exists, and with a useertype1 parameter, and copy the result.

Composite assignment

The composite assignment operators given in Table 4.4 are specified as E1 OP = E2 form, where E1 is a modified L value that is a very amount type, E2 is one of the following:

* An arithmetic type

* A pointer, if the OP is or

-E1 OP = E2 forms the same operation with E1 = E1 OP E2, but E1 is only evaluated once.

A composite assignment for enumeration type will generate an error message. If the left operating is a pointer type, the right operand must be a constant expression of a pointer or must be equal to 0; if the left operation is a integer, the right operand must not be a pointer type.

Comma operator

The comma operator allows two statements to group, one of which is expected.

Grammar expressions:

Assignment expression

Expression, assignment expression

The comma operator has a combination law from left to right. Two expressions separated from left to right from left to right. The left operation is always evaluated, and all side effects are completed before the right operation.

Consider expressions:

E1, E2

The type and value of the expression is the type and value of E2, and the result of the evaluation of E1 is discarded. If the right operand is a l value, the result is a l value.

The comma has special meanings (eg, in the actual parameters of the function or in the set initializer), the comma operator and its operands must be included in parentheses. Therefore, the following function call is not equivalent: // Description function

Void func (int, int);

Void func (int);

Func (arg1, arg2); // Call FUNC (int, int)

FUNC ((arg1, arg2)); // Call FUNC (int)

This example shows a comma operator: for (i = j = 1; i j <20; i = i, j -);

In this case, each operand of the third expression of the for statement is independently evaluated, and the left operation number i = i first is evaluated; and then the right operand is j - to be evaluated.

Func_one (X, Y 2, Z);

FUNC_TWO ((x -, y 2), z);

In the FUNC_ONE function call, three parameters separated by commas are passed: X, Y 2, and Z; in the FUNC_TWO function call, parentheses force the compiler to interpret the first comma as the sequence evaluation operator. This function call passes two parameters to FUNC_TWO, the first parameter is the result of the sequence evaluation operation (x -, y 2), has the value and type of expression Y 2; the second parameter is Z.

Expression with conditional operator

Conditional operator (? :) is a three-mean operator (which has three operands). The conditions of the condition operator are as follows:

* Before proceeding, the first operand is evaluated, and all side effects are completed.

* If the first operand evaluation is true (one non-0 value), the second operand is evaluated.

* If the first operand evaluation is false (0), the third operand is evaluated.

The result of the conditional operator is the result of the evaluation, namely the second or third result. There is only one value of the two operands in the conditional expression.

Grammatical conditional expression:

Logic or expression

Logic or expression? Expression: conditional expression

Conditional expression has no combination law. The first operand must be an integer or pointer type, the following rules are used for the second and second operands:

* If the two expressions are similar, the result is that type.

* If both expressions are arithmetic types, the common arithmetic conversion (included in Chapter 3 "Standard Conversion") is executed to convert them to a common type.

* If both expressions are type or one is a pointer type, the other is a constant expression of value 0, and the pointer conversion is performed to convert them to a common type.

* If both expressions are reference types, reference conversions are executed to convert them to a common type.

* If both expressions are Void types, the public type is a Void type.

* If two expressions are a given class type, the utility type is the class type. Any combination of the second and third operands not included in the previous list are illegal. The type of the result is a common type, and if the second and third operands are the same type and are the L value, the result is a l value.

E.g:

(VAL> = 0)? Val: -Val

If the condition is true, the expression is equal to VAL; otherwise, the expression is equal to -VAL.

Belt expression

C requires a constant expression in the following description, ie, an expression that is constant:

* Array boundaries

* Selector L bit length specification in the case statement

* Enumeration initializer

grammar

Constant expression:

Conditional expression

The only legal operand in a constant expression is:

* Text

* Enumeration

* Instructions for initialization with constant expressions as constant values

* SIZEOF expression

Non-integer constants in constant expressions must be converted (explicitly or implicitly) as legitimate. Therefore, the following code is legal:

Const Double size = 11.0;

Char charray [(int) size];

The conversion in a constant expression is integrated into an integration, except for the number of operators used as the SizeOF operator. All other types or derived types are illegal.

The comma operator and assignment operator cannot be used in a constant expression.

Expression with explicit type conversion

As described in Chapter 3, "Standard Conversion", C provides implicit type conversion. When you need to control your application more accurately, you can specify an explicit type conversion.

Explicit type conversion operator

C allows explicit type conversion using syntax similar to the function call syntax, and a simple type name follows an expression table enclosed in parentheses, which makes up an object specified by the specified expression, and the following example gives one Go to the explicit type conversion of int type: int i = int (d);

The following example uses the modified version of the Point class defined in "Function Call Results":

#include Class Point {public: // Defines the default constructor Point () {_x = _y = 0;} // Define another constructor Point (int x, int y) {_x = x; _y = y;} // Define "Accessor" function unsigned & x () {return _x;} unsigred & y () {return _y;} void show () {cout << "x =" <<} <"," << "y =" << _y << "/ n";} private: unsigned _x; unsigned _y;}; void main () {Point Point1, point2; // assignment to Point1 display conversion to 10, 10) Point1 = Point (10, 10); // By assigning the display conversion of a 20 to the unsigned type to make X () as a l value to use Point1.x () = unsigned (20); Point1.SHOW ); // Give Point2 default Point object Point2 = Point (); point2.show ();}

The output of this program is

: x = 20, y = 1

0x = 0, y = 0

Although the previous examples are illustrated by the explicit type conversion of constants, these conversions are performed on the object. The following code segment illustrates this situation:

INT i = 7;

Float D:

D = float (i);

The display type conversion can also be specified by the "Model Conversion" syntax, the previous example, rewritten with the modeling conversion syntax:

D = (float) i;

When switching from a single value, the shape conversion and function form are transitions have the same result. However, in the functional form syntax, you can specify multiple parameters for the conversion. This difference is important for user-defined types.

Consider a POINT class and its conversion:

Struct Point {Point (short x, short y) {_x = x, _y = y;} ... short _x, _y;}

...

Point Pt = Point (3, 10);

The previous example uses the functional form of conversion, which shows how to convert two values ​​(one X, one as Y) into user-defined type Point.

Important: Use explicit type conversion to be careful because they cover the internal type check of the C compiler.

grammar

Model conversion expression:

Single-eyed expression

(Type Name) Model Conversion Expression

Model tags must be used to conversions without a simple type name (such as pointer or reference type). The conversion of types represented by a simple type name can be written in any part of any two. See "Type Indicators" in Chapter 6, "Description" on what forms a simple type name.

Type definitions within the styling conversion are illegal.

Legal conversion

If the conversion can be implemented with a standard conversion, you can make explicit conversions from a given type to another type, and the result is the same. The conversion described in this section is legal, any other non-displayed conversion (for a class type) defined (a class type).

If the pointer is large enough to save an integer value, a whole value can be explicitly converted to a pointer, and the pointer to a integer value can be transferred back to the pointer, and its value is the same. This consistency is given by the following equation (where P represents a pointer to any type):

P == (TYPE *) Integer conversion (P) with explicit conversion, the compiler does not check if the converted value is suitable for new types, except from the pointer to the integer, and vice versa.

This section describes the following conversion:

* Conversion pointer type

* Convert empty pointer

* Convert to ahead reference class type

* Convert to reference type

* Conversion between member pointer types

Conversion pointer type

One object type pointer can be explicitly converted to another object type pointer, indicating that a pointer to void * is considered to be a pointer to any object type.

. A base class pointer can be explicitly converted to a derived pointer, as long as the following conditions are satisfied:

* There is a non-blurred conversion.

* At any point, the base class is not illustrated as virtual.

Since the conversion to the VOID * type can change the representation of an object, it does not guarantee the conversion type1 * void * type2 * equivalent to the conversion type1 * type2 * (the change in value is only).

When such a conversion is performed, the result is a pointer to the sub-object indicating the source object of the base class.

See Chapter 9, "Delicious Class" for more information on blurred and virtual base class.

C allows objects or function pointers to explicitly switch to the VOID * type. If the function pointer type has enough bit to accommodate the object pointer type, the object pointer type can explicitly convert to the function pointer.

The pointer of the constant object can be explicitly converted to a very varied pointer, and the result of this conversion points to the source object. References of constant type objects or constant type objects can be switched to a reference to a very amount type. The result is a reference to the source object. Source objects are likely to indicate constants because it retains constants during the duration. Therefore, an explicit conversion causes such security failures, and allows modifications to this object to be unsure in this case.

The pointer of the Volatile type object can be switched to a pointer to a non-Volatile type, and the result of this conversion refers to the source object. Similarly, the Volatile type object can be switched to a non-Volatile type reference.

Convert empty pointer

The empty pointer (0) is converted to itself.

Convert to a forward reference class type

A class has been explained but has not been defined (a forward reference) can be used for pointer styling conversion, in which case the compiler returns a source object pointer, not a possible child object pointer.

Convert to reference type

Any of its address can be converted to an object of a given pointer type, or can also be converted to analog type, for example, any other address can be converted to a type char * can also be converted to type char. There is no constructor or class conversion function to be called to generate a conversion to the reference type.

Objects or values ​​can be converted to class type objects, which only provides a constructor or conversion operator for this purpose. For more information on these user-defined functions, see Chapter 11, "Conversion Constructor" in the Special Member Function.

A reference for a base class to a reference to a derived class (or vice versa) is the same as the pointer. The results of the modeling conversion to the reference type are one l value, and the result is converted to other types of results not the l value. The operation performed on the results of the pointer or reference modeling conversion is still executed on the source object.

Conversion between member pointer types

One member pointer can be converted to a different member pointer type by following the following rules: The two pointers must be the member pointer of the same class or must be two classes of the member pointer, and one is non-blurred from another derived. When converting member pointer functions, the returned type of parameters must match.

Expression with member pointer operator

Member pointer operator. * And -> * Returns the value of a specific class member of the object specified on the left side, and the following example shows how to use these operators:

#include Class Window {public: void pressure (); // Remove the window to Heavy Int WindowsId;};

/ / Define the derived type PMFNPAINT and PMWindowID

// These types are Paint () and WindowID member pointers, respectively.

Void (Window :: * Pmfnpaint) () = & window :: Paint;

Int window :: * PmWindowID = & window :: windowid;

Void main () {window awindow; window * pWindow = new window; // Normal call Paint function, then use member pointer awindow.paint (); (awindow. * pmfnpaint) (); pWindow -> Paint (); (PWindow -> * pmfnpaint) (); // Since * does not have a function call connection is close, it is necessary to parentheses int ID; // Retrieve window number ID = awindow. * PMWindowID; ID = PWindow -> * PMWindowID;} In the above example, PMFNPaint member pointer is used to call member functions Paint. Another member of the PMWindowID is used to access the WindowID member.

grammar

PM-expression:

Model conversion expression

PM-expression. * Model conversion expression

PM-Expression -> * Model Conversion Expression

Bi-purpose operators. * Combine the first operand (ie, a class type object) and the second operand (ie, must be a member pointer type).

Bottom Operators -> * The first operand (ie, must be a pointer to class type object) and the second operand (ie, must be a member pointer type).

In an expression containing. * Operator, the first operand must be a class type of the member pointer specified in the second operand, and can access the pointer or non-motion from that class and can be accessed. An accessible type.

In an expression containing-> * operator, the first operand must be a "class type pointer" type of the second operand specified type, or must be a type from that class non-motion. Consider the following classes and blocks:

Class Baseclass {Publc: BaseClass (); // Base class constructor Void funCl ();

// Describe a pointer to the member function func1

Void (Baseclass :: * PMFNFUNC1) () = & baseclass :: func1;

Class Derived: public baseclass {public: derived (); // derived class constructor Void func2 ();};

// Describe a pointer to the member function func2

Void (Derived :: * PMFNFUNC2) () = & Derived :: func2;

Void main () {baseclass abase; derived aderived; (ABASE. * PMFNFUNC1) (); // Viab: is BaseClass definition (ABASE. * PMFNFUNC2) (); // Error: Cannot go to access the party category pointer with the base class () (); // Viable: Derived is from BaseClass non-scratch-derived (aderived. * PMFNFUNC2) (); // Viable: for derived definition}.

* Or -> * The result of the member pointer operator is an object or function of the type specified in the member pointer description. Therefore, in the previous example, the result of the ADerived. * PMFNFUNC1 () expression is a pointer to the function of returning the VOID. If the second operation value is 1, this result is also worth 1.

Note: If the result of one of the member pointer operators is a function, then the result can only be used as an operator of the function call operator.

Expression semantics

This section explains when and in what kind of order is evaluated, including the following topics:

* Sequential order

* Order

* Fuzzy expression

* Expression in the expression

Ask the order

This section discusses the order in which the expression is evaluated, but does not explain the grammar or semantics of the operators in these expressions, this chapter provides a complete reference for each of these operators than before.

The expression is obtained in accordance with its priority and packet conditions of its operator (Chapter 1 "Specification" in Chapter 1 gives the relationship of the C operator applied to the expression). Consider this example:

#include void main () {int a = 2, b = 4, c = 9; cout << a b * c << "/ n"; cout << a (b * c) << "/ n"; cout << (a b) * c << "/ n";} The output of the front code is:

38

38

54

The expression evaluation order given in 4.1 determines by the priority and combined law of the operator:

1. The multiplication (*) has the highest priority in this expression, so the B * C sub-expression is first requisitioned.

2. The addition ( ) has a secondary priority, so A is added to the complex of B and C.

3. Left movement (<<) has the lowest priority in the expression, but there are two times, since the left-moving operator is packet from the left to right, the left sub-expression is first requisitioned, and then the right sub-expression.

When parentheses are used for packets, they change the priority of the expression and the order of evaluation, as shown in Figure 4.2.

4.2 Those expressions are purely for side effects, in which case the information is converted to a standard output device.

Note: The left motion operator is used to insert an object into a class output stream object. When used with the input and output stream, sometimes it is called an "insert" operator. For more information on the input and output flow libraries, see the "Microsoft Visual C 6.0 Run Reference" volume of the Microsoft Visual C 6.0 Reference.

Sequence point

An expression can only change the value of an object once between continuous "order points".

Microsoft Special Office

C language definition is now not specified in order. For any expression containing C operators and operators that do not contain overload, Microsoft C uses the same order in the same way as ANSI C. When the operator is overloaded, the semantic from the order of order is changed from the order of operation. Microsoft C uses the following order:

* Logic and operators (&&)'s left operating number, before proceeding, logic and operators have completely evaluated, and all side effects are completed. The right operand that does not guarantee the logic and the operator will be evaluated.

* Logic or operators (||) left operating, before proceeding, logical or operator's left operating number is completely evaluated, and all side effects are completed. The right operand that does not guarantee logic or operator will be evaluated.

* The left operator of the comma operator is completely evaluated before the continuation, and all side effects are completed. The two operands of the comma operator are always evaluated.

* Function call operator, a function of a function calls expressions and all parameters, including the default parameters, before entering the function, and all side effects are completed. There is no specification order between parameters or function call expressions.

* The first operand of the condition operator, before proceeding, the first operand of the conditional operator is completely evaluated, and all side effects are completed.

* End of a complete initial expression, such as an end of an initialization in the description statement.

* Expression in the expression statement, the expression statement is composed of a selection (;) after an optional expression. Expressions are completely evaluated for their side effects.

* In a control expression in a selection (IF or SWITCH) statement, the expression is completely evaluated before the code is executed, and all side effects are completed.

* Control expressions in a While or DO statement. The expression is completely evaluated before the next repetition of the While or DO cycle, and all side effects are completed.

* For each of the three expressions, each expression is completely evaluated before entering the next expression, and all side effects are completed.

* The expression in the returning statement is completely evaluated before the control returns to the call function, and all side effects are completed.

Microsoft End

Blurred expression

Some expressions are fuzzy, and when the value of an object in the same expression is modified more than once, these expressions have been frequently occurred. These expressions depends on a particular evaluation order, but in the language, there is no definition order, considering the following example:

INT i = 7;

FUNC (i, i);

The C language does not guarantee the order in which the parameters in the function call is invoked. Thus, in the above example, FUNC may receive 7 and 8 or 8 and 8 for its parameters, depending on whether the parameter is from left to right or from right to left. Expression method

The C language specifies certain compatibility when specifying the operand, and Table 4.5 shows the type of operand that requires an operator that requires an operator of the Type type.

Table 4.5 Operators acceptable operand type

Desired type permit type

TYPE NST TYPE

Volatile Type

Type &

Const Type &

Volatile Type &

Volatile Const Type

Volatile Const Type &

TYPE * YPE * COUST

Type * volatile

Type * Volatile Const

Const Type Ype

Const Type

Const Type &

Volatile Type Type

Volatile Type

Volatile Type &

Since the previous rules can always be used in the combination, a constant pointer to a volatile object can be provided in a point where a pointer is desired.

Model conversion

C language regulations: If a class derived from the base class contains a virtual function, the pointer to that base class type can be used to call the implementation of the virtual function existing in the derived class object. A class containing virtual functions is sometimes referred to as a "polymorphism class".

Since a derived class fully contains definitions of all the base classes they are derived, a pointer can be safely styled to arbitrarily point to any one of these base classes. A pointer to the base class is given, which is safe, and if the object being pointed is actually a type derived from the base class, it is safe. In this case, the actual subject is said to be "complete object", the base class pointer is said to be a "sub-object" that is integrity. For example, consider the class levels given in Figure 4.3.

A type C object, as shown in Figure 4.4.

Given an instance of a class C, there is a B child object and an A child object. An example of C including a and B sub-object is "complete object".

Use the run type information, you can check if a pointer is really pointing to a complete object, and whether it can safely shape another object in its hierarchy. The Dynamic_cast operator can be used to complete these types of modeling, which also performs the necessary operational check to make the operation security.

Model operator

There are several modeling operators to be C language specific. These operators aim to remove the fuzziness and danger in the form of an old C language shape. These operators are:

* Dynamic_cast used for multi-state types of conversion

* static_cast used for non-multi-state types of conversions

* const_cast is used to remove const, volatile, and __unaligned properties

* ReinterPret_cast is used for a simple and then explained

Use const_cast and reinterpret_cast as a last means because these operators have the same risk as the old shape form. But they still need to be used to completely replace the old model form.

Dynamic_cast operator

Expression Dynamic_cast

(Expression) Converting the Expression operand to a Type-ID type object, the Type-ID must be a pointer or a reference for the previously defined class or "Void pointer". If the Type-ID is a pointer, the type of Expression must be a pointer or if the Type-ID is a reference, it is a 1 l value.

grammar

Dynamic_cast

(Expression)

If the Type-ID is a direct or indirect base class pointing to Expression, the result is a pointer to the unique sub-object of the type-id type, for example:

Class b {...};

Class C: Public B {...};

Class D: public c {...};

Void f (d * pd) {c * pc = Dynamic_cast (pd); // Viable: c is a direct base class, PC pointing to the C sub-object B * PB = Dynamic_Cast (PD) ); // Viable: B is a indirect base class, PD pointing to the C sub-objects of PD ...} This type of conversion is called upward shape, because it makes pointers to move upward, from a derived class to A derived source class. The upward shape is an implicit conversion.

If the type-id is a void *, an actual type of run check is performed to determine the actual type of Expression, and the result is a pointer to the complete object pointing to the Expression.

E.g:

Class a {...};

Class b {...};

Void f () {a * pa = new a; b * Pb = new b; void * pv = Dynamic_cast (pa); // PV Now point to one object of type A ... PV = Dynamic_Cast (PB); // PV Now points to an object of type B}

If the Type-ID is not a void *, perform the run check to see if the object pointing by Expression can be converted to type-id. If the version of Expression is a base class of the type-id type, perform the run check to see if the Expression does point to a complete object of type-id type, if it is true, the result is a complete object of type-id type pointer.

E.g:

Class b {...};

Class D: public b {...};

Void f () {b * pb = new D; // is not clear but can feasible B * PB2 = New B; D * PD = Dynamic_cast (pb); // Viable: PB does point to a D ... D * pd2 = Dynamic_cast (PB2); // Error: PB2 points to a B instead of a D, PD2 == null ...}

This type of conversion is called downward because it makes the pointer down to the class level, from a given class to a class that is derived from it.

In the case of multiple inheritance, the possibility of fuzziness is introduced. The class level given in Figure 4.5 can be considering:

The pointer to an object of type D can be safely styled to B or C. However, if D is styled to a A object, which example will be A. This will result in a fuzzy modeling error. In order to overcome this problem, you can perform two non-blurred shapes. E.g:

Void f () {d * pd = new d; A * PA = Dynamic_cast (pd); // error: blurred B * PB = Dynamic_cast (PD); // first line style B A * PA2 = Dynamic_Cast (pb); // Feasible: non-ambiguous}

Further ambiguity is introduced when you use a virtual base class. Consider the class level shown in Figure 4.6:

In this level, A is a virtual base class, and see "Virtual Base" in Chapter 9, "Detected Class" in Chapter 9, for a definition of a virtual base class. A genus of a given E class and a pointer to the A sub-object, and Dynamic_CAST that rotates to B's pointer will fail because of fuzziness. You must first reach the complete E object, then take the right B object in a non-ambiguous manner along the level.

Consider the class level shown in Figure 4.7.

A pointer to an object of a given type E, a pointer to the D sub-object, navigating from the D sub-object to the leftmost A sub-object, there can be three conversions. You can perform a Dynamic_cast to transfer from the D pointer to the E pointer, then a conversion (for Dynamic_CAST or implicit conversion) from E to B, the last implicit conversion from B to A. E.g:

Void f (d * pd) {e * pe = dynamic_cast (pd); B * PB = pe // upward shape, implicit conversion A * PA = Pb; // upward shape, implicit conversion}

The Dynamic_cast operator can also be used to perform "cross-style". Use the same class level, for example, a pointer can be made from the B child object to the D sub-object, as long as the complete object is E type. Considering the shape of the shape, it is indeed possible to convert a pointer to the D pointer to the leftmost A sub-object only within two steps. You can convert from D to B shape, then a implicit conversion from b to A. E.g:

Void f (d * pd) {b * pb = Dynamic_cast (pd); // Cross the shape conversion A * PA = Pb; // upward shape, implicit conversion}

An empty pointer value is converted to a nacad value of the target type by Dynamic_CAST.

When you use Dynamic_cast

When Expression cannot be completely converted to the Type_id type, the run check will result in failure of the styling. E.g:

Class a {...};

Class b {...};

Void f () {a * pb = new a; b * Pb = Dynamic_cast (pa); // failed, unsafe; b is not derived from A ...}

The value of a failure to the pointer type is an empty pointer. The stylosis of the fails to the reference type discards an BAD_CAST exception.

BAD_CAST exception

The Dynamic_cast operator discards a bad_cast exception, as a failure of the reference type

The value of the shape, the interface of Bad_cast is:

Class Bad_cast: PUBLIC Logic {public: BAD_CAST (const __exstring & what_arg): logic (what_ary) {} void raise () {handle_raise (); throw * this;} // virtual __exString what () const; // inherited }

STATIC_CAST operator

STATIC_CAST

Expression The expression converts Expression to the type TYPE_ID type given in the expression. No run type check is executed to ensure the security of the conversion.

grammar

STATIC_CAST

(Expression)

The STATIC_CAST operator can be used, for example, to convert a base class pointer to a derived class pointer, such a conversion is not always secure,

E.g:

Class b {...};

Class D: public b {...};

Void f (b * pb, d * pd) {d * pd2 = static_cast (pb); // is not safe, PB may only point to B * PB2 = static_cast (pd); // Safety conversion ...}

In contrast to Dynamic_CAST, there is no run check on the static_cast conversion of PB. Objects from PB may not be a D type object, and the case of using * PD2 may be catastrophic. For example, calling a function is a member of the D class but not Class B, which may cause access to conflicts.

Dynamic_cast and static_cast operators can move a pointer in a class level, but Static_cast only relies only information provided in the styling statement, so it is unsafe. E.g:

Class b {...};

Class D: public b {...};

Void f (b * pb) {d * pd1 = Dynamic_cast (pb); d * pd2 = static_cast (pb);}

If PB really points to an object of type D, PD1 and PD2 will result in the same result. If PD == 0, they will also get the same result.

If PB points to an object of type B, but does not point to a complete D class, DynamiC_cast will be enough to know to return 0. However, Static_cast relies on the programmer's insistence that the PB points to an object of the type D and simply returns the pointer to the assumed D object.

Therefore, STATIC_CAST can achieve the opposite implicit conversion, in which case the result is undefined, the result is left to ensure that the result of the STATIC_CAST conversion is safe.

These actions are also applicable to other types other than class types. For example, Static_CAST can be used to convert from int to char. However, the result character may not have enough bits to keep the entire value, and then leave the programmer to ensure that the result of static_cast conversion is safe. The STATIC_CAST operator can also be used to perform any implicit conversions, including standard conversion, and user-defined conversions. E.g:

Typedef unsigned char Byte

Void f () {char ch; INT i = 65; float f = 2.5; double db1; ch = static_cast

(i); // from int to char

DB1 = static_cast

(f); // from Float to Double

...

i = static_cast

(CH);

]

The STATIC_CAST operator can explicitly convert a integer value to an enumeration type. If the integer value is not built within the range of enumeration values, the enumeration result value is uncertain.

The STATIC_CAST operator converts an empty pointer value to the null pointer value of the target type.

Any expression can be explicitly converted to the Void type with the Static_cast operator, and the target Void type can selectively include const, volatile, or __unaligned attributes.

The Static_cast operator cannot be styled to remove const, volatile or _ _Unaligned attribute. See "const_cast operator" for information on removing these attributes.

Const_cast operator

The Const_cast operator can be used to remove const, volatile, and _ _Unaligned attributes from a class.

grammar

Const_cast

(Expression)

Any object type pointer or a pointer to a data member can be explicitially converted to the exact same type, with const, volatile, and __unaligned qualifiers. For pointers and references, the results will point to the source object, point to the same member as the source (non-styling) pointer of the data member pointer. Due to the type of reference object, the write operation of the results of the pointer, reference, or data member pointer will result in undefined action

. The Const_cast operator converts an empty pointer value to the null pointer value of the target type.

Reinterpret_cast operator

The ReinterPret_cast operator allows any pointer to be converted to any other pointer type, it also allows

Any integer is converted to any pointer type, and vice versa. Abuse the ReinterPret_cast operator can easily lead to unsafe, unless the desired conversion is an inherent low level, otherwise one of the other modeling operators should be used.

grammar

Reinterpret_cast

(Expression)

The ReinterPret_cast operator can be used to use CHAR * to INT * or One_Class * to Unrelated * This internal non-secure conversion.

Results of ReinterPret_cast In addition to the model returns to their source type, it is not possible to be safely used for any other situation, and other usage is not portable.

The ReinterPret_cast operator cannot model the CONST, VOLATILE or __UNALIGNED properties, and see the const_cast operator on the removal of these attributes.

The ReinterPret_cast operator converts an empty pointer value to the null pointer value of the target type.

Run type information

Run Type Information (RTTI) is a mechanism that allows the object's type to be determined during program execution. RTTI is added to the C language, because many class liberators are implementing this feature themselves, which leads to incompatibility between libraries. Therefore, it is clear that the language level supports running type information.

For the sake of clarity, this discussion of RTTI is almost entirely limited to the pointer. But the concept of discussion is also applicable to reference.

Run type information has three main C language elements:

* Dynamic_cast operator, used for multiple types of conversions. For more information, see section "Dynamic_cast operator" in this chapter.

* TypeID operator, used to specify the exact type of an object.

* TYPE_INFO class, used to maintain type information returned by the TypeID operator.

TypeID operator

The TypeID operator allows the type of object to be determined at runtime.

grammar

TYPEID (TYPE_ID) TYPEID (Expression)

The result of a TypeID expression is a constant Type_info &. Its value is a reference to the Type_info object. Objects indicate the type of Type_ID or Expression, which depends on which form is used by TypeID. More information see "Type_info classes" later in this chapter.

The TypeID operator performs an operation check when it is used for a Polymorphic class type, and the active type of the object cannot be determined by the provided static information. These conditions are:

* A class reference

* A pointer, use * indirect reference

* A subscript pointer (such as []) (note that the subscript of the pointer with a picker is usually unsafe)

If Expression points to a base class type, and the object is actually derived from the base class, the result is the Type_info reference for the derived class. Expression must point to a plurality of types, ie classes with virtual functions. Otherwise, the result is Type_info of the static class pointed out in Expression. Moreover, the pointer must be indirectly referenced, so the object it points to is used. Without indirect reference pointers, the result will be the TYPE_INFO of the pointer instead of what it points to. E.g:

Class Base {...};

Class Derived: Public Base {...};

Void f () {derived * pd = new derived; base * pb = pd; ... const type_info & t = typeid (pb); // T Keep Type_info pointer const type_info & t1 = typeid (* pb); // t1 keep Delivery info ...}

If Expression indirectly references a pointer, and the value of that pointer is 0, TypeId discards a Bad_TypeID exception. If the pointer does not point to a valid object, the exception __non_rtti_object is discarded.

If the expression is neither a pointer to the base class of an object, the result is a Type_info reference that represents the static type of Expression.

Bad_typeid exception

In some cases, the TypeID operator discards a Bad_TypeID exception, and the interface of the Bad_TypeID is:

Class Bad_TypeId: PUBLIC Logic {public: Bad_TypeId (const char * what_arg): logic (what_arg) {} void raise () {handle_raise (); this;} // virtual __exstring what () const; // inheritance of};

See "TypeID operator" for more information.

TYPE_INFO class

The TYPE_INFO class describes the type information generated by the compiler in the program, which effectively stores a pointer to the name of the name, and the Type_info class also stores an encoded value suitable for comparing two types of equivalent or finishing sequence. The coding rules and finishing order of the type are not specified and can vary from different programs.

To use the Type_info class, you must contain the typeInfo.h header file.

class type_info {public: virtual ~ type_info (); int operator == (const type_info & rhs) const; int operator = (const type_info & rhs) const; int before (const type_info & rhs) const; const char * name () const;! Const char * RAW_NAME () Const; private: ...};

== and! = Operators can be used to compare equal or unequality with other Type_info objects, respectively. There is no connection between the type of finishing order and the inheritance relationship. Use Type_info :: Use Type_info :: before the member function. Do not guarantee the same results in different programs or even the same procedure in different operations. In this case, the front TYPE_INFO :: is similar to the address (&) operator. The Type_Info :: Name member function is a representative type, the 0 termination string of the person-readable name returns a char * constant. The poached memory is cached and never be dispensed directly.

The Type_inf :: Raw_name member function returns a char * constant for the 0 termination string representing the object type ornament. The name is actually existing in its decoration format to save space. Thus, this function is faster than Type_info :: Name because it does not require a non-decorative name. The string returned by the Type_info :: Raw_name function is useful in the comparison operation, but is not readable. If you need a person's readable string, use the Type_info :: Name function.

The type information of the polymorphic class is generated only when the specified / GR (enabled type information) compiler option.


New Post(0)