"Effective C + + notes" construction/destruction/assignment

Source: Internet
Author: User

Automatic function of the compiler

The compiler can secretly create a default constructor, a copy constructor, a copy assignment operator, and a destructor for class.


To dismiss a function that is automatically provided by the compiler, member functions can be declared private and not implemented.

For example, if you intend to support assignment operations within a class containing reference members or const members, you must define the copy assignment operator yourself, because reference and const variables cannot be modified.

Also, if a base classes declares the copy assignment operator as private, the compiler will refuse to generate a copy assignment operator for its derived classes.

Class Homeforsale {public    :        ...;    Private: ...        ;        Homeforsale (const homeforsale&);  Only the declaration        homeforsale& operator= (const homeforsale&);};
In order to detect all copy actions at compile time, such as from the member function or the friend function, you can design a base class specifically designed to prevent copying actions. For example, the following uncopyable:
Class Uncopyable {    protected:        uncopyable () {}        ~uncopyable () {}    private:        uncopyable (const uncopyable&);        uncopyable& operator= (const uncopyable&);}; Class Homeforsale:private Uncopyable {//directly inherits public    :        homeforsale (int i) {            x = i;            cout<<x<<endl;        }        ~homeforsale () {            cout<<x<<endl;        }    Private:        int x;};

Why is the Uncopyable function declared as protected and the inheritance relationship private? You can think by contacting the following.


Destructors

C + + explicitly states that when a derived class object is deleted by a base class pointer, and the base class takes a non-virtual destructor, the result is undefined--the actual execution usually occurs when the derived component of the object is not being sold Destroy.

Workaround: Give base Class A virtual destructor.


To determine whether a destructor is required: the base class for polymorphic (with polymorphic properties) should declare a virtual destructor. If class has any virtual functions, it is almost certain that there should also be a virtual destructor. The purpose of Classes's design is not to declare a virtual destructor if it is not used as base Classes, or not to have polymorphic rows.


Sometimes you want to have an abstract class, but you don't have any pure virtual functions on your hands, you can declare a pure virtual destructor for the class that you want it to be abstract.

Class Awov {public     :          virtual ~awov () = 0;} Awov::awov () {}    //must provide a definition, no words will go wrong
Destructors should never spit out exceptions. If a function called by a destructor might throw an exception, the destructor should catch any exceptions and then swallow them (not propagate) or end the program. As the following procedure:
Dbconn::~dbconn () {    try{db.close ();}    catch (...) {        //make a running record, note that the call to close failed.        Std::abort ();//  End Program    }}dbconn::~dbconn () {    try{db.close ();}    catch (...) {        //Make operation record, note the call to close failed, swallow the error    }}
However, if the customer needs to react to an exception during the operation of an action function, then class should provide a normal function (rather than a destructor) to perform the operation.
Class Dbconn {public    :        ...;        void Close ()  //function        {            db.close () for customer use;            closed = true;        }        ~dbconn ()        {            if (!closed) {                try{  //client closes                    db.close () when not closed;                }                catch (...) {                    //make a running record, note that the call to close failed ...;}}        }    Private:        DBConnection db;        BOOL closed;}


Note that during the base class construct, the virtual function is not a virtual function. Therefore, do not call the virtual function during construction and destructor, such calls never fall to derived class (compared to the layer that currently executes constructors and destructors).

If you want to implement a function similar to virtual functions, so that every time during construction the appropriate version of the function is called, you can make derived classes the necessary construction information up to the base class constructor.

Class Transaction {public    :        explicit Transaction (const std::string& loginfo);        void Logtransaction (const std::string& loginfo) const; Become a non-virtual function ...        ;}; Transaction::transaction (const std::string& loginfo) {    ...;    Logtransaction (loginfo);  Non-virtual Call}class buytransaction:public transaction{public    :        buytransaction (Parameters)            : Transaction (createlogstring (parameters))  //Pass the log message to the base class constructor        {            ...;        }    Private:        static std::string createlogstring (parameters);};
The createlogstring declaration above is important for static, making it impossible to accidentally point to "member variables that have not been initialized within the initial immature Buytransaction object". (Here is a question of why the logtransaction function in a base class does not need to be declared static.) )

The Copying function assignment operator must return a reference to the left argument of the operator, which is a protocol that should be followed, as well as for all assignment-related operations. such as + =, =.

To process "self-assignment" in operator=.

In this respect, the traditional method is to carry out "proof and test" in operator= to test:

widget& widget::operator= (const widget& RHS) {     if (this = = &RHS) return *this;  Test and     delete pb;     PB = new Bitmap (*RHS.PB);     return *this;}

However, the above may have exception security, if there is an exception due to the allocation of insufficient memory, such as New Bitmap, the Widget will have a pointer to the deleted Bitmap object.

We can consider automatically getting "self-assigning security" by letting Operator= have "exceptional security". And many times a well-orchestrated set of statements can be used everywhere to safely (and self-assigning security) code.

widget& widget::operator= (const widget& RHS) {     bitmap* porig = PB;   First save the original pointer     PB = new Bitmap (*RHS.PB);//Make PB point to a copy of *PB     delete porig;   Delete the original PB     return *this;}
So, it can be concluded that any function that operates on more than one object while multiple objects are the same object is still behaving correctly.


The Copying function should ensure that all member variables within the object and all base class components are copied: All local member variables are copied, and the appropriate Copying functions within all base classes are called


In order to eliminate duplicate code, do not attempt to implement another copying function with one of the copying functions. The common function should be put into a third function and called by two coping functions, which are often private and often named Init.

"Effective C + + notes" construction/destruction/assignment

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.