Chapter 10 Quote and Copy Construction Functions
First, there is a certain rule when using the reference: 1) When the reference is created, it must be initialized. (The pointer can be initialized at any time.) 2) Once a reference is initialized to point to an object, it cannot be changed to a reference to another object. (The pointer can point to another object at any time.) 3) It is impossible to have N u L. reference. It must be ensured that the reference is connected to a legal storage unit.
Second, parameter delivery guidelines
When passing the parameters to the function, people should be delivered through constant references. Although it seems to seem to be considered only for efficiency (the efficiency is not considered when designing and assembling the program), there will be a lot of dangers in this chapter. (The usage of constant references not only improve efficiency, but also avoiding the troubles of copy constructor) The copy constructor needs to pass the value, but this is not always possible. This simple habit can greatly improve the efficiency: the pass value needs to call the constructor and the destructor, however, if you do not want to change the parameters, you can pass through the constant reference, it only needs to put the address stack. In fact, only one situation is not suitable for delivery address, this is the only way to pass the value, otherwise it will destroy the object (not the external object, this is not the caller usually expect) (question, what At this time, this is necessary to pass the value?)
Third, the function calls the stack frame
When the compiler is called to generate a code, it first stacks all the parameters and then calls the function. Inside the function, generate code, and move the stack pointer to the function local variable to provide a storage unit. ("Under" is relative, when the stack, the machine stack pointer may increase may also be reduced.) In the assembly language call, the CPU calls the function of the function in the program code, so the assembly language return You can use this address to return to the call point. Of course, this address is very sacred because there is no program that will be lost. This provides a look at the stack frame in C All, which has been assigned a storage unit in the function. Figure 1 Function Parameters Returns the address local variable Reflections on the storage location of the function return value: 1) Stack: What will happen if the call function attempts to return the value in the stack from a normal function. Since any part of the stack returns the address cannot be hit, the function must be stack the value under the returned address. However, when assembly language return is executed, the stack pointer must point to the return address (or just below it below, which depends on the machine.), So before the Return statement, the function must move the stack pointer up to clear all local variables. If we try to return a value from the return address in the stack, because the interrupt may occur at this time, it is the most vulnerable to attack. This time ISR will move the stack pointer down, save the return address and local variables, so that we override our return value. (Your ISR has been moved, but the value is still placed in the following memory, it has been returned to the program process. Because this is suddenly coming out of another function call, it covers the content you just now.). 2) Global Data Area: Our next idea may be a value in the global data area, but this is not feasible. Retrieving means that any function can interrupt any other functions, including the same function as it. Therefore, if the return value is placed in the global area, we may return to the same function, which will rewrite the return value. It is also the same for recursive. 3) Register: Register, the problem is how to do when the register is not enough to store the return value. The answer is to put the address of the return value like a function parameter, allowing the function directly to copy the return value information to the destination. Don't solve problems, but also higher efficiency. The program will put your return value when calling, and then put the value directly in a memory area in the called function, and record the memory address. When returning, copy the memory content to the variable assigned to you. Chapter 11 Operator Overload
First, grammar
The number of parameters in the function parameter table depends on two factors: 1) The operator is a yuan (a parameter) or binary (two parameters). 2) Operators are defined as global functions (for one yuan is a parameter, for binarys, two parameters) or member functions (for a dollar no parameters, for binary is a parameter-object change to left parameters).
Second, self-increment and self-reduction
The overloaded and-number operators have two difficulties, since they want to call different functions based on their appearance of the object (prefix) or the back (suffix) in which they act. Solution is very simple, but some people find that they are easily confusing. For example, when the compiler sees a (first induced), it calls Operator (a); but when the compiler sees A , it calls Operator (A, int). That is, the compiler differs from these two forms by calling different functions.
Fourth, parameters and return values
1) For any function parameters, if you only need to read from the parameters without changing it, it is default to transfer it by constant reference. Ordinary arithmetic operators (like and - numbers, etc.) and Boolean operators do not change parameters, so it is the main way for use in const reference. When a function is a class member, it is converted to a Const member function. Just for the assignment operator that will change the left parameters (Operator-Assignment, like =) and operator '=', the left parameter is not constant, but because the parameters will be changed, the parameters are still transmitted by address. . 2) The return value that should be selected depends on the type desired by the operator. (You can do anything you want to do for parameters and return values) If the effect of the operator is generating a new value, a new object as a return value will be required. For example, Integer :: Operator must generate a sum of an operand object. This object is returned as a constant to the path, so as a left value is not changed.
3) All assignment operators change the left value. In order to make the assignment result for a chain expression (like a = b = c), it should be able to return a reference to the left value just changed. But should this reference should be constant or nonconst? Although we read the expression A = b = c from left to right, the compiler is analyzed from the right direction, so it is not necessary to return a nonconst value to support chain assignment. However, it is sometimes desirable to operate the object just assigned, such as (a = b) .foo (), this is the B assignment to a re-adjust foo (). Therefore, the return value of all assignment operators should be NonConst reference for the left value. (For the convenience of cascading, although A has changed in a function, it is still necessary to return a reference; here should return NonConst because foo is a member function, so it is not a const function, so if the value returned by A = B is CONST, then the FOO function will not be called)
4) For logical operators, people want to get at least an int return value, preferably BOOL return value. (In most compilers support C built-in BOOL type, library functions developed using int or typedef equivalents)
5) Because there is a prefix and a suffix version, the self-increasing and self-reduction operators have appeared two difficulties. Both versions change the object, so you can't see this object as a const. Therefore, the prefix version returns the value after the object is changed. This way, use the prefix version we only need to return * this as a reference. Since the suffix version returns a value before the change is changed, it is forced to create a single object that represents this value and returns it. Therefore, if we want to maintain our original intention, the suffix must return. (Note that we often find self-increasing and self-reduction operations to return an INT value or BOOL value, for example, to indicate whether there is a cycle sub-item at the end of the table). The question now is: These should be returned by constant or press NonConst? If the object is allowed to be changed, some people write expressions ( a) .foo (), the foo () effect is on a. But for expression (A ). Foo (), foo () acts on the temporary object returned by the suffix operator . The temporary object is automatically set to Const, so the compiler is marked. But in order to consistency, the two are Const more meaningful, just like it. Because you want to give your own and self-reduction operations, they need to think about things. That is to say, Return Const data.
1. Press const to return to press Const to return to the pass value. It starts to look subtle, so it is worth explaining. Let's consider the binary operator number. It is assumed that it is used in an expression like F (A B), and the result of A B is a temporary object, which is used for F () call. Because it is temporary, it is automatically set to const, so no matter whether it makes the return value or not doing so. 2. Return Efficiency When you return a new object, you should pay attention to the form of use. For example, with an operator number: return integer (Left.i Right.i); the beginning looks like a "call to a constructor", but it is not the case. This is a temporary object syntax, which is described above: "Create a temporary object and return it." For this reason, we may think that if you create a naming local object and return it, it will be the same. actually not. If it is shown below, three things will occur. First, the TMP object is created, and it is called with this constructor. Then, the copy constructor copies the TMP to the return value external storage unit. Finally, the destructor is called when TMP is at the end of the scope. Integer TMP (Left.i Right.i); Return TMP; Instead, the method of "return to temporary objects" is completely different. Looking at this situation, the compiler understands that there is no other need for the created object, just returns it, so the compiler directly creates the object in the memory unit outside the return value. Because not really create a local object, only a single normal constructor call (no copy constructor is required), and the destructor is not called. Therefore, this method does not require what is expensive, and efficiency is very high.
Five, smart (smart) pointer
If you want to package a pointer to make this pointer secure, or in a normal loop sub-use, it is especially useful. The loop is an object that can act on the package container or collection of other objects, and one of them is selected without providing direct access to the package container. (I often found the bag container and loop in class function.) The dexterity pointer must be a member function. It has an additional atypical content: it must return an object (or reference), this object also has a smart pointer or pointer, which can be used to select this delegation pointer.
six,
Basic Rules Operators are recommended to use all one yuan operator members = () [] -> must be members = - = / = * = ^ = & = | =% = >> = << = member All other binary operations Non-member
Seven, copy constructor and operator =