More effective C + + clause 25 to Blur constructor and Non-member function

Source: Internet
Author: User

1. Virtual constructor

In principle, constructors cannot be virtual: Virtual functions are used to implement "behavior that differs depending on type", that is, to invoke different entities based on the dynamic type of the pointer or reference to the object being bound, but the constructor is used to construct the object, which naturally does not have a concept of dynamic type before the object is constructed. It is impossible to talk about virtual and non-imaginary. The so-called Virtual-constructor is actually "imitation virtual-constructor", it is not constructor in nature, but can produce different types of objects, thus realizing " Virtual-constructor "feature, consider the following hierarchy of inheritance for managing news reports:

classnlcomponent {//abstract base class, a component for real-time communication containing at least one pure virtual function Public:        ...};classTextBlock: Publicnlcomponent { Public:    ... //does not contain any pure virtual functions};classGraphic: Publicnlcomponent { Public:    ... //does not contain any pure virtual functions};classNewsLetter {//a real-time communication consists of a series of Nlcompnent objects Public:     ...Private: List<NLComponent*>Components ;};
View Code

Newsletter may be stored on disk, in order to read the newsletter object from disk into memory, it may have a constructor that accepts the istream& parameter:

classNewsLetter { Public: NewsLetter (IStream&str); ...Private: List<NLCompnent*>compnents; ...}; Newsletter::newsletter (IStream&str) {     while(str) {Read the next compnentObject  fromstr; Add theObjectTo the list of This; Newsletter's compnents;    }}
View Code

NewsLetter (istream& str) can also be implemented by a readcompnent function with its main function:

classNewsLetter { Public: NewsLetter (IStream&str); ...Private:    //reads the next nlcompnent data from STR, produces the component (Compnent), and returns a pointer to it    Staticnlcompnent* Readcompnent (istream&str); List<NLCompnent*>compnents; ...}; Newsletter::newsletter (IStream&str) {     while(str) {//Adds a pointer returned by readcompnent to the compnents list endcompnents.push_back (readcompnent (str)); }}
View Code

Here Readcompnent produces a new Nlcompnent derived object (either TextBlock or graphic) and returns a nlcompnent pointer, because it can produce different types of objects, so it is called a virtual Constructor. Virtual constructor is useful in many cases, one of which is to read object information from a disk (or network or tape).

A special virtual Constructor--copy virtual constructor that returns a pointer to a new copy of its caller, and the dynamic type of the pointer is determined by the type of the object that called it. TextBlock and graphic's copy of virtual constructor can look like this:

classnlcomponent { Public:    //statement Virtual copy constructor    VirtualNlcomponent * Clone ()Const=0; ...};classTextBlock: Publicnlcomponent { Public:    VirtualTextBlock * Clone ()Const //Virtual copy Constructor{return NewTextBlock (* This); }    ...};classGraphic: Publicnlcomponent { Public:    VirtualGraphic * Clone ()Const //Virtual copy Constructor{return NewGraphic (* This); }     ...};
View Code

In this way, clone realizes the function of virtual copy constructor.

Note that although the derived class redefined the virtual function of base class, the declaration must be the same as in base class, but if the function return type is a pointer (or reference) to the base class, then derived Class can return a pointer (or reference) to its derived class. Therefore, although the above clone is a virtual function, it can return a different pointer type.

Based on the above nlcompnent virtual copy constructor, you can implement a (normal) copy constructor for newsletter:

classNewsLetter { Public: NewsLetter (Constnewsletter&RHS); ...Private: List<NLComponent*>Components ;}; Newsletter::newsletter (Constnewsletter&RHS) {    //iterate through the list of RHS, using the virtual copy constructor of each element to copy the element to the Compnents list of this object.     for(List<nlcomponent*>::const_iterator it =rhs.components.begin (); It! = Rhs.components.end (); + +it)//it points to the current element of rhs.compnents, calls the element's clone function to get a copy and adds to the end of the Compnents list of this objectComponents.push_back ((*it)clone ());}
View Code

2. Virtual Non-member function.

Just as constructors cannot be falsified, the Non-member function cannot be falsified in principle-it is not even a member function. Consider implementing the << operator for TextBlock and graphic to make << To TextBlock and graphic to achieve different behavior, the direct idea is to be <<, but in fact this can not achieve:<< the first operand is ostream&, that is to say << as member function, you can only become a member of the Ostream class, but this is not possible. So << can only be used for non-member functions, which can be taken with virtual constructor similar strategies implemented by virtual Non-member function

classnlcomponent { Public:    Virtualostream& print (ostream& s)Const=0; ...};classTextBlock: Publicnlcomponent {bbs.theithome.com Public:    Virtualostream& print (ostream& s)Const; ...};classGraphic: Publicnlcomponent { Public:    Virtualostream& print (ostream& s)Const; ...}; Inline Ostream&operator<< (ostream& S,Constnlcomponent&c) {    returnC.print (s);}
View Code

Non-member and virtual copy constructor are similar: Write a virtual function to do the actual work, and then a non-virtual function call the virtual function. In addition, in order to avoid the extra cost of function calls (after all operator<< only one sentence, Not worth the cost of the reload stack), the non-virtual function can be inlin.

To this end, you can make Non-member copy constructor depending on one of its arguments, to realize the virtualization based on more than one argument, see clause 31.

More effective C + + clause 25 to Blur constructor and Non-member function

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.