More effective tive C ++ reading abstract (I. Basic Topic II. Operator) Item1-8

Source: Internet
Author: User

0. "Introduction"
Conventions and terms:
1. Add P to the pointer, and add r to the reference.
2. In the call to operator =, LHS and RHS are abbreviated as "left-hand side" and "right-hand side" respectively.
3. ctor stands for "constructor", and dtor stands for "destructor"

 

I. Basic topics
Item 1. differentiate pointer and reference:
Reference should be used in the following cases->
① When you know that you want to refer to an object and no longer refer to other things
② When some operators are implemented, if the semantic requirements of these operators make the pointer unfeasible. (For example, operator [])

Use pointer in the following cases->
① When you know that you want to refer to it, you may not point to anything.
② It is possible to point to different objects at different times, that is, to change the pointer

 

Item 2. c ++ type conversion is preferred:
Static_cast: similar to C-style type conversion
Const_cast: remove the const attribute of an object.
Dynamic_cast: Performs downward or horizontal Security conversion for an inheritance system
Reinterpret_cast: type conversion between function pointers (almost unportable)

 

Item 3. Do not use polymorphism in Arrays:
Because the object of the derived class is generally larger than the object of the base class, pointer operations may cause problems for polymorphism. Because Array Operations almost always involve pointer operations, arrays and polymorphism cannot be used together.
When Delete [] array is used, a problem occurs.

 

Item 4. Avoid unnecessary Default constructors:
A default constructor should be provided for all classes. Otherwise
① It is difficult to create an array of objects on the stack (theclass classarray [10])
② It cannot be used as a type parameter of many template-based container classes, because the template must create an array (same as ①) about the template parameter types ).
③ The virtual base class without the default constructor requires all its derived classes to know and understand the meanings of the parameters of the virtual base class constructor and provide these parameters, regardless of the hierarchy of inheritance.

However, if you do not have enough information to fully Initialize an object, it will make other member functions complex, because you must check whether the variables are meaningful. Providing meaningless Default constructors will also affect the running efficiency of classes.

 

Ii. Operators
Item 5. Be careful with user-defined conversion functions:
The compiler may call an implicit type conversion function when you do not want or think of it. For example:
Example 1

Class rational {<br/> Public: <br/> ...... <Br/> operator double () const; <br/>}; <br/> rational R (1/2); // R = <br/> cout <R; // rational has not operator <

In this case, the compiler does not report an error. Instead, it automatically finds the operator double so that the entire call is successful.
Solution:

Class rational {<br/> Public: <br/> ...... <Br/> double asdouble () const; <br/> };

It must be called explicitly. Just like the member function c_str of string in STL.

 

Example ① can be avoided by not declaring the type conversion operator, but here is a more exaggerated example ②:

Template <class T> class Array {<br/> Public: <br/> array (INT lowbound, int highbound); <br/> array (INT size ); // constructor of a single parameter, maybe edevil <br/> T & operator [] (INT index); <br/> ...... <br/>}; <br/> bool operator = (const array <int> & LHS, const array <int> & RHs) {<br/> array <int> A (10); <br/> array <int> B (10); <br/> ...... <br/> if (a = B [I]) {...} // A shoshould have been a [I] <br/> };

The subscript of A is knocked out, but the compiler does not report an error. Instead, the following code is generated:
If (A = static_cas <array <int> (B [I]) {...} the call is successful (note that there is a space between the last two> symbols, why ?). This code generates a temporary Array Using B [I.

 

The constructor of a single parameter can only useExplictKeyword to overcome.Template <class T> class Array {<br/> Public: <br/> ...... <br/> explict array (INT size); // <br/> T & operator [] (INT index); <br/> ...... <br/> };

 

In addition, a proxy technology can be used to reconstruct a class:

Template <class T> class Array {<br/> Public: <br/> class arraysize {<br/> Public: <br/> arraysize (INT numelements ): thesize (numelements) {}< br/> int size () const {return thesize ;}< br/> PRIVATE: <br/> int thesize; <br/> }; <br/> array (INT lowbound, int highbound); <br/> array (arraysize size); // note the differences in parameters <br/> ...... <br/> };

Array <int> A (10) can still pass, and the int is converted to arraysize. But a = B [I] cannot pass, because in order to make the call successful, an array <int> on the Right of = is required, so we need to first convert int (that is, B [I]) to arraysize, and then convert arraysize to array <int>, but the second conversion is not allowed.

 

The author suggests that implicit type conversion by the compiler usually has more disadvantages than advantages. Therefore, do not provide type conversion functions unless necessary.

 

Item 6. Differentiate the prefix form and suffix form of the auto-increment and auto-increment operators:

Class upint {<br/> Public: <br/> upint & operator ++ (); // + I <br/> const upint operator ++ (INT ); // I ++, Postfix </P> <p> upint & operator -- (); // -- I <br/> const upint operator -- (INT ); // I --, Postfix </P> <p> upint & operator ++ = (INT); <br/> };

When a suffix is called, the compiler will quietly pass a 0 as the parameter. But this int parameter does not actually work, just to distinguish between prefix and suffix.
A temporary object must be created internally in the form of a suffix. The const In the suffix form is used to prevent chain suffixes (such as I ++ ).

 

Item 7. Do not reload "&", "|" and ",":
Because operator & (expression1, expression2) and operator | (expression1, expression2) cannot guarantee which of expression1 and expression2 is evaluated first (actually all are evaluated ), therefore, the short-circuit Evaluation Method of C and C ++ cannot be used, so it is evaluated from left to right.
Similarly, if you overload the comma operator, you cannot guarantee the order from left to right.

 

Item 8. Understand the meaning of new and delete in different situations:
① Operator New-> its only responsibility is to allocate memory, which is ignorant of constructors. This is the essential difference between operator new and new.
Operator new returns an unprocessed pointer, and the new operator converts the pointer to an object.
When the compiler sees the statement: string * PS = new string ("Memory Management"), it generates the following code:

// Operator new <br/> void * Memory = Operator new (sizeof (string); <br/> // This code can only be called by the compiler, it is essentially a constructor <br/> call String: string ("Memory Management") on * memory; <br/> // convert pointer type <br/> string * PS = static_cas <string *> (memory); <br/>

Conclusion: If you only want to allocate memory, you can call operator new without calling constructor. If you want to customize the memory allocation process when the heap object is created, you should write your own operator new function and then use the new operator. New will call your customized operator new.

 

② Placement New-> Create an object in a memory with a pointer pointing:
Class widget {...} <br/> widget * constructwidgetinbuffer (void * buffer, int widgetsize) <br/> {return New (buffer) widget (widgetsize);} <br/>

Summary: If you want to create an object in a memory with a pointer pointing to, use placement new.

 

③ Correspondingly, operator Delete only releases memory, while the delete operator calls operator Delete and then calls the destructor.
When the compiler sees the statement: delete pS;, it generates the following code:
PS-> ~ String (); // call the destructor
Operator Delete (PS); // release memory


Summary:If you only want to process the original uninitialized memory, you should completely bypass the new and delete operators. Instead, you can directly call operator new to obtain the memory and operator Delete to release the memory.
Void * buffer = Operator new (50 * sizeof (char ));
...
Operator Delete (buffer );

Therefore, if placement new is used to create an object in the memory, you should avoid using the delete operator for this memory, because Delete releases the memory by calling operator Delete, but this memory was not originally allocated by operator new. In this case, the object should be explicitly released (usually placed in the object's destructor, that is, explicitly calling the destructor ).

 

④ Operator new [] corresponds to operator Delete.
String * PS = new string [10];
Delete [] pS;

Contact Us

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

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

A Free Trial That Lets You Build Big!

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

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

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

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