"Effective C + +" Reading notes 2

Source: Internet
Author: User

Article 13: Managing Resources with objects

With RAII, the resource is immediately placed in the management object, and the management object uses the destructor to ensure that the resource is freed.

To prevent resource leaks, use the Raii object, which obtains resources in constructors and frees resources in destructors.

The two commonly used RAII classes are tr1::shared_ptr and tr1::auto_ptr. The former is usually a better choice, because its copy behavior is more intuitive. If you select Auto_ptr, the copy action will point the copied object to null.

Article 14: Careful copy behavior in the Resource management class

The copy Raii object must replicate the resources it manages together, so the copy behavior of the resource determines the copy behavior of the Raii object.

n General and common RAII copy behavior is: suppress copy, use reference counting method.

Article 15: Provide access to the original resource in the resource management class

n APIs often require access to raw resources, so each RAII class should provide a way to obtain the resources it manages

n access to the original resource may be transformed by a display or by an implicit conversion. Explicit conversions are generally more secure, but implicit conversions are more convenient for customers.

Article 16: Paired use new and delete to take the same form

Consider the following typedef:

typedef std::string ADDRESSLINES[4];

Since addresslines are arrays, if you use new as such;

std::string *pal=new Addresslines;

Then you must match the delete in the array form:

Delete pal; No behavior defined

delete []pal; That's right

n If you use [] in the new expression, you must also use [] in the corresponding delete expression. If you do not use [] in the new expression, you must not use [] in the corresponding delete expression.

Article 17: Placing a Newed object into a smart pointer with a standalone statement

Consider the following code:

int priority (); Priority of handlers

void Processwidget (std::tr1::shared_ptr<widget> pw,int priority);

Processwidget (std::tr1::shared_ptr<widget> (new Widget), priority ());

The above code can be compiled, but not exceptionally secure, because the order in which the new widget and priority () is called is indeterminate. If the order of the calls is this:

1. Execute the new Widget

2. Call Priority

3. Call the Tr1::shared_ptr constructor

If an exception occurs when the priority is called, the resources requested by the new widget will have a memory leak.

The way to avoid these problems is to separate the statements:

Std::tr1:shared_ptr<widget> PW (newwidget);

Processwidget (Pw,priority ());

This way, the compiler cannot arbitrarily select the order in which statements are executed.

N Stores the Newed object in a smart pointer in a separate statement. If you do not, once an exception is thrown, it is possible to cause an imperceptible resource leak.

Article 18: Make the interface easy to use correctly, not easy to misuse

n Good interfaces are easy to use correctly and are not easily misused, and you should strive to achieve these properties in all of your interfaces.

n Promotion of proper use includes interface consistency and compatibility with built-in types of behavior.

n ways to prevent misuse include establishing new types, restricting operations on types, constraining object values, and eliminating customer resource management responsibilities.

Article 19: Design class like design type

Designing good calsses is a daunting task, because the design of types is a daunting task. Good types have natural syntax, intuitive semantics, and one or more efficient implementations. In C + +, a class definition under a bad plan is not likely to achieve any of these goals, and even the efficiency of class member functions may be affected by how they are declared.

Clause 20: Prefer to pass a reference to a const instead of a value

Consider the following classes:

class Window

{

Public:

std::string name () const;

Virtual void display ()const;

};

classwindowwithscrollbars: public Window

{

Public:

Virtual void display ()const;

};

voidPrintnameanddisplay (Window W)

{

Std::cout<<w.name () <<endl;

W.display ();

}

If you call the above function and give it a Window object, a window is called within the function::d isplay, instead of calling the display function of the derived class, the solution to the problem is:

void Printnameanddisplay (const window&w)

{

Std::cout<<w.name ();

W.display ();

}

There are two advantages to the method of transmitting the reference, the other is to improve the execution efficiency of the program and to avoid the object segmentation problem.

n instead of passing values as a reference to a constant, the former is usually more efficient and avoids cutting problems

n the above rules do not apply to built-in types, as well as STL iterators and function objects. For them, the value of the pass is often more appropriate.

Article 21: When you must return an object, don't be paranoid about returning its reference

If the overloaded multiplication operator is as follows:

Const RATIONAL & operator * (constrational &lhs,const rational &RHS)

{

Rational result (LHS.N*RHS.N,LHS.D*RHS.D);

return result;

}

This function returns a reference to a local variable and is therefore wrong.

Looking at a different version:

Const RATIONAL & operator * (constrational& lhs,const Rational & RHS)

{

Rational *result=newrational (LHS.N*RHS.N,LHS.D*RHS.D);

return *result;

}

This function completes initialization of the object, but the allocated memory on the heap cannot be freed because of a memory leak.

When you must return an object, the correct notation for the function is: let the function return a new object.

The function can be rewritten as follows:

inline const RATIONAL operator * (constrational &lhs,const rational &RHS)

{

Return Rational (LHS.N*RHS.N,LHS.D*RHS.D);

}

to get the right results, you have to endure the cost of a constructor and destructor.

Article 22: Declaring a member variable as private

N Remember to declare the member variable as private, which gives the customer access to data consistency, fine-grained access control, promise constraints, and provide class authors with full flexibility.

Clause 23: Prefer to replace the member function with Non-member non-friend function

Consider the following classes:

class Webbrower

{

Public:

voidclearcache ();

voidclearhistory ();

voidremovecookies ();

};

If you want to call three functions in a row, you can design a member function like this:

class WebBrowser

{

Public:

voidcleareverything (); Call the above three functions

};

This function can also be replaced with the following version:

voidclearbrowser (WebBrowser & WB)

{

Wb.clearcache ();

Wb.clearhisttory ();

Wb.removecookies ();

}

This non-member non-friend version is better than the version of the member function because it does not have access to private members, providing greater encapsulation.

Clause 24: If all parameters require type conversion, use non-member functions for this purpose

Consider the definitions of the following classes:

Class Rational

{

Public

Constrational operator * (const Rational *RHS) const;

...

}

Try invoking the following method:

result=onehalf*2; That's right

Result=2*onehalf; Error

This parameter is the qualified participant of the implicit type conversion only if the parameter is listed in the parameter list.

N If you want to make result=2*onehalf a legitimate call, you can write the operator* () function in the form of a non-member function.

This function must be a non-member function if a type conversion is required for all parameters of a function.

Article 25: Consider writing out a swap function that does not throw an exception

n when the Std::swap is not efficient for your type, provide a swap member function and make sure that the function does not throw an exception

n If you provide a memberswap, you should also provide a non-member swap to invoke the former, and for the class, also special Std::swap


"Effective C + +" Reading notes 2

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.