Go on ...
(b). Construction/Destruction/assignment operations
_______________________________________________________________________________________________________________ _____________________
Article 11: Handling "self-assignment" in operator=
#1Make sure that operator= has good behavior when the object is self-assigned. These include "self-assigning security" and
"Exception security", self-assignment security can be compared with the address of "src object" and "Dest object"
, and "Exception security" can be achieved by carefully arranged statements such as:
widget& widget::operator= (const widget& RHS) { bitmap* porig= pb; PB = new Bitmap (*RHS.PB); Delete Porig; return *this;}
Because the "self-assignment" test will increase the original code and the target code, and introduce the decision control flow, so if
When the probability of "self-assignment" is very low, the introduction of evidence and test will reduce the efficiency of operator=, at this time
The certificate should not be introduced into the test.
In addition, Copy-and-swap technology is also a solution to the "self-assignment" process.
#2. Determines if any function operates more than one object, and when multiple objects are the same object, its
The behavior is still correct.
_______________________________________________________________________________________________________________ _____________________
Article 12: Do not forget every ingredient when copying an object
#1. When writing a copying function (copy constructor or copy assignment), make sure that:
(1). Copy all local member variables. (2). Call all the appropriate copying functions within the base classes.
#2Do not attempt to call the Copy assignment function with the copy constructor, or use the Copy assignment function
Call the copy constructor, you should put the common function in the third function, for the two copying function calls,
Usually this function is named Init.
_______________________________________________________________________________________________________________ _____________________
(iii). Resource Management
_______________________________________________________________________________________________________________ _____________________
Article 13: Managing Resources with Objects
#1To prevent resource leaks, use the Raii object (Resource acquisition is initialization),
They get the resources in the constructor and release the resources in the destructor.
Reason: Consider the following function
void F () { while (somecase) { investment* PINV = Createinvestment (); Createinvestment () is a factory function, PINV is a base class pointer, pointing to a derived class object ... Delete Pinv;} }
In the case of ... There is a return statement, similar to the one in ... In the continue or Goto statement will cause the program
Premature exit, rather than fortunately "delete Pinv", which will lead to memory leaks, the Raii object is precisely for solving
This problem exists.
(Careful coding avoids this, but in the case of program maintenance, because the resource management policy is not known, the encoding
People are likely to be ... The Return,continue or Goto is added to the error, resulting in this situation. )
#2Ensuring that resources are immediately put into management objects and interfaces separated will increase the risk of resource leaks.
(very likely to throw an exception during separation)
#3. Two commonly used RAII classes are tr1::shared_ptr and auto_ptr respectively. The former is usually
Better choice because its copy behavior is intuitive and RCSP (reference-counting smart pointer).
If you select Auto_ptr, the copy action will cause the managed resource of the copied RAII to point to null.
Two usage examples:
investment* createinvestment ();std::tr1::shared_ptr<investment> PINV (Createinvestment ()); std::auto_ptr <Investment> PINV (Createinvestment ());
#4. Tr1::shared_ptr and Auto_ptr both do delete in the destructor instead of delete[], which means
Do not use the dynamically allocated array for them, and if you do, consider the boost library
Boost::scoped_array and Boost::shared_array classes.
_______________________________________________________________________________________________________________ _____________________
article 14: Beware of copying behavior in resource management classes
#1Because the resource managed by the Raii object is a member variable of the Raii object, when the Raii object is copied, the resource's
The copying behavior determines the copying behavior of the Raii object.
#2Common and common RAII class copying behaviors are: Prohibit copying, execute reference counting method,
Deep copy of underlying resources, transfer of ownership of bottom resources, and so on.
Prohibit copying:
Class Lock:private Uncopyable{public: ...}
Execution reference Counting method:
void Lock (mutex* pm), void Unlock (mutex* pm), class Lock{public: explicit Lock (mutex* PM)://With Mutex initialization shared_ptr, mutexptr (PM, unlock) //and unlock as the delete { lock (Mutexptr.get ()); } Private: std::tr1::shared_ptr<mutex> mutexptr;}
When class lock copying behavior occurs, the mutexptr is copied, the reference count is incremented, and the compiler is called
When the destructor is automatically generated, Mutexptr's destructor is called to reduce the reference count when the reference count is 0
, the delete unlock () is invoked to unlock the mutex.
Copy Bottom resource:
A copy, similar to the standard string std::string, copies a pointer contained in the string, and it points to the
Heap of memory.
Transfer ownership of bottom resources:
Class Lock{public: explicit Lock (mutex* PM)://With Mutex initialization auto_ptr mutexptr (PM) { Lock (Mutexptr.get ( )); } Private: std::auto_ptr<mutex> mutexptr;}
_______________________________________________________________________________________________________________ _____________________
Article 15: Provide access to the original resource in the Resource management class
#1. APIs often require access to raw resources, so each RAII class should provide
A way to "get the resources that they manage."
#2Access to the original resource may be transformed by a display or by an implicit conversion. Generally, the conversion is more secure,
But implicit conversion is more convenient for customers.
Class Font{public:explicit Font (Fonthandle fh): F (FH) {} ... Fonthandle get () const {return F;} Show conversion operator Fonthandle () const {return F;}//implicit conversion private:fonthandle f;}
_______________________________________________________________________________________________________________ _____________________
Article 16: Paired use new and delete to take the same form
#1If you use [] in new, you must also use [] in the corresponding delete expression. If you're in new
Do not use [] in an expression, be sure not to use [] in the corresponding delete expression.
#2When you use new, the memory is allocated (via operator new), and for this memory there is a
(or more) constructors are called (referred to as custom data types). When you use Delete, for this memory
One (or more) destructors are called (referred to as custom data types) and then memory is freed
(via operator delete).
#3When using new[], a memory unit with an "array size record" in memory is allocated to
In delete[], the size of the object array can be clarified, for some compilers, it will be the first object array
Memory unit as the "array size record".
_______________________________________________________________________________________________________________ _____________________
Article 17: Placing a Newed object into a smart pointer with a standalone statement
#1The Newed object is stored in the (placed) smart pointer in a stand-alone statement. If you do not do this, once the exception
Be thrown, potentially causing an imperceptible resource leak.
For example:
Processwidget (std::tr1::shared_ptr<widget> (new Widget), priority ());
For the C + + compiler, the new widget occurs before the Tr1::shared_ptr constructor,
But the priority () function execution is not known, considering that it occurs in the second straight position, such as:
1." The new Widget executes
2. Priority () call
3. Tr1::shared_ptr Constructor Call
Throwing an exception during the priority () call will lose the pointer returned by the new widget without being placed in
Tr1::shared_ptr, while the latter is precisely for resource memory management,
It should be said that the program code is separated into:
Std::tr1::shared_ptr<widget> PW (new Widget);p rocesswidget (PW, priority ());
This ensures that the compiler chooses the order of execution in the new widget and the Tr1::shared_ptr constructor
is tightly linked, which solves the problem of resource leaks.
_______________________________________________________________________________________________________________ _____________________
Effective C + + reading notes (clause 11-17)