"Effective C + +" 4th Chapter design and Declaration (2)-Reading notes

Source: Internet
Author: User

Chapter Review:

The 1th chapter of effective C + + makes himself accustomed to c++-reading notes

Effective C + + 2nd structure/destructor/assignment operation (1)-Reading notes

Effective C + + 2nd structure/destructor/assignment operation (2)-Reading notes

"Effective C + +" Chapter 3rd resource Management (1)-Reading notes

"Effective C + +" Chapter 3rd Resource Management (2)-Reading notes

"Effective C + +" 4th Chapter design and Declaration (1)-Reading notes

"Effective C + +" 4th Chapter design and Declaration (2)-Reading notes

"Effective C + +" 8th custom new and delete-reading notes

Article 22: Declaring a member variable as private

First, there are two small reasons to support you declaring a member variable as private.

(1) Consistency of the interface.

If the public interface is all functions, then the client does not have to consider the need for parentheses when calling, because each call is a function and must be enclosed in parentheses.

(2) fine-grained access control.

Using functions allows you to have more precise control over the handling of member variables, and if you make member variables public, everyone can read and write to it.

The most important thing is that private provides encapsulation:

If you access a member variable through a function, you can change a calculation later to replace the member, and the class client will never know that the inside of the class has changed, just recompile.

Assuming that you declare a member variable as public or protected and the customer starts using it, it is difficult to change everything involved in that member variable. Too much code needs to be rewritten, tested, rewritten, compiled. From the point of view of encapsulation, there are actually only two kinds of access rights: private and others (no encapsulation is provided).

Please remember:

(1) Remember to declare the member variable as private. This gives the customer access to data consistency, fine-grained access control, guaranteed constraints, and provides the class author with full flexibility.

(2) protected is not more encapsulated than public.

Clause 23: Better replace the member function with Non-member and non-friend functions

Here's a class:

class webbrowser{public:    void  clearcache ();     void clearhistory ();     void removecookies ();};

The user wants to make these three interfaces by providing a function that defines a member function to call these three functions.

void Webbrowser::cleareverything ()    // member functions, calling ClearCache, ClearHistory, and Removecookies{    ClearCache ();    ClearHistory ();    Removecookies ();}

Of course, this feature can also be provided through a non-member function:

void Clearbrowser (webbrowser& WB)        // non-member function {    wb.clearcache ();    Wb.clearhistory ();    Wb.removecookies ();}

What is the best thing to consider now?

The object-oriented code requires that the data and functions that manipulate the data should be bundled together, which means that it suggests that member is a better choice. This suggestion is wrong and a misunderstanding of the true meaning of object-oriented.

The object-oriented code requires that data should be encapsulated as much as possible. Contrary to intuition, cleareverything brings a lower encapsulation than clearbrowser. because the Non-member non-friend function does not have access to private within class.

Note: The consideration here is that member and Non-member non-friend a choice when they provide the same function. Friends has the same access rights to private as the member function.

Clause 24: If all parameters require type conversion, use the Non-member function for this

It is generally not good to have class support for implicit type conversions, but there are exceptions. Assuming that a class represents a rational number, it is reasonable to allow the integer "implicit conversion" to be rational.

class rational{public:    Rational (int0int1);     int const;            // Molecular Access functions    int const;        // Denominator access function };

You want this class to support multiplication operations. It is possible to declare operator* as a member function.

class rational{public    : ...     Const operator* (constconst;};

This design is not a problem to use in this way:

Rational oneeighth (18); Rational onehalf (12= onehalf * ONEEIGHTH;        // Okay, no problem . result = result * ONEEIGHTH;                // Yes, no problem .

When you want to use a blending operation:

2;            // Okay, no problem . 2 * ONEHALF;            // error, not satisfying the Exchange law

Essentially the above usage is equivalent to the following:

result = Onehalf. operator* (2);        // result = Onehalf * 2;     2. operator* (onehalf);        // result = 2 * onehalf;

So you can see why you don't meet the law of exchange. To support mixed operations, you need to set operator* to the Non-member function.

Const operator* (constconst rational& RHS) {    return Rational ( Lhs.numerator () * Rhs.numerator (), Lhs.denominator () * rhs.denominator ());

The following call is OK:

Rational Onefourth (142;        // Yes, no problem . 2 * Onefourth;        // Yes, no problem .

One thing to note here is that the constructor must not be declared as explicit, otherwise the value 2 of the integral type cannot be implicitly converted to rational object .

Please remember: This function must be non-member if you need to convert all the parameters of a function, including the metaphorical parameter referred to by the this pointer.

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

The SWAP function assigns the values of two objects to each other. By default, swap can be done by the swap algorithm provided by the STL. The typical implementation is as follows:

namespace std {    template<typename t>    void swap (t& A, t& b)    {        T temp (a);        = b;         = temp;    }}

This algorithm can be exploited as long as the T supports the copy (by copying the constructor and the copy assignment operator).

However, in some cases, the default swap behavior is often less efficient. For example, point to an object with a pointer. Consider the following class:

classwidgetimpl{ Public:...Private:    intA, B, C; Vector<Double>v;};classwidget{ Public: Widgets (Constwidget&RHS); Widgets&operator=(Constwidget&RHS) {        ...        *pimpl = *(Rhs.pimpl); ...    }Private: Widgetimpl*Pimpl;};

If we were to swap widget objects, the default algorithm would copy 3 widget objects and 3 Widgetimpl objects, which was inefficient. In fact, we just need to displace the pointer to the Pimpl.

To solve the problem of efficiency, we need to tell Std::swap that when exchanging widget objects, you just need to exchange pointers. Std::swap can be customized for widgets.

namespace std {    template<>    void swap<widget> (widget& A, widget& b)    {        swap (A.pimpl, B.pimpl);             // Exchange pointer value     }}

It's just a thought, generally we can't change anything in Std, we can make the widget declare a swap public member function to do the replacement work, and then Std::swap.

class widget{public:    void swap (widget& other )    {          Using Std::swap;                //         Swap (Pimpl, Other.pimpl);}    ;

Note: the member swap function must never throw an exception. Because one of the best uses of swap is to help class provide strong exception security.

Remember: when STD::SWAP is not efficient for your type, provide a swap member function and make sure that the function does not throw an exception.

Additional NOTE: clause 25 There is some other knowledge, I do not understand the special good, there is no explanation, but the whole problem is caused by the swap efficiency, the next review to add.

"Effective C + +" 4th Chapter design and Declaration (2)-Reading notes

Related Article

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.