C + + handle class

Source: Internet
Author: User

First, container and inheritance

When you save an object that has an inheritance relationship in a container, the derived class is cut if it is defined to hold the base class object, and if it is defined to save the derived class object, then it becomes a problem to save the base class object (the base class object is cast to the derived class object, and the member defined in the derived class is not initialized).

The only viable option is to hold a pointer to the object in the container. However, users are required to manage objects and pointers. A common technique in C + + is the wrapper class (cover) or the handle class (handle). Use the handle class to store and manage class pointers.

The handle class generally accomplishes two things:

    1. Manages pointers, which are similar to the functions of smart pointers.

    2. To implement polymorphism, using dynamic binding, a pointer can either point to a base class or to a derived class.

There are two important design considerations for wrapping a handle to an inheritance hierarchy:

    1. As with any class that holds pointers, you must determine what to do with the copy control. A handle that wraps an inheritance hierarchy usually behaves like a smart pointer or a value.

    2. The handle class determines whether the handle interface is masked or does not mask the inheritance hierarchy, and if the inheritance hierarchy is not masked, the user must understand and use the objects in the base hierarchy (objects in theunderlying hierarchy).

Here's a simple example I wrote myself to illustrate the problem:

This example program includes a base class, a derived class, and a handle class.

Where the base class has 2 private members, the numeric m_base and the program name name. The derived class has a new private member, M_der.

Derived classes and base classes have virtual function compute. The base class compute it computes the base class member M_base squared. The compute of a derived class computes the sum of m_base squares and m_der.

The handle class has two data members, each of which is a pointer to a reference count ( this must be a pointer, the value of the copy pointer when copied , a reference count to ensure that only one of the instantiated objects has a single quote), and a pointer to the base class or its derived class.

#include <iostream>#include<string>#include<exception>using namespacestd;//base classclassBase { Public:    //Basic ConstructorBase (intM_base =1,stringName ="Base"): M_base (m_base), name (name) {cout<<"Base Constructor called!"<<Endl; }    //copy ConstructorBase (ConstBase &Base): Base (Base. M_base,Base. Name) {cout<<"Base copy called"<<Endl; }    VirtualBase *clone ()Const {        return NewBase (* This); }    Const stringGetName () {returnname; }    Virtual intCompute ()Const {        returnM_base *m_base; }    Virtual~Base () {cout<<"Base deleted"<<Endl; }protected:    intm_base; stringname;};classDerived: PublicBase { Public:    //Basic ConstructorDerived (intM_base,stringNameintm_der): Base (m_base, name), M_der (m_der) {cout<<"Derived Constructor called"<<Endl; }    //copy ConstructorDerived (ConstDerived &derived): Derived (Derived.m_base, Derived.name, Derived.m_der) {cout<<"Derived copy called"<<Endl; }    VirtualDerived *clone ()Const {        return NewDerived (* This); }    Virtual intCompute ()Const {        //calling methods defined in the parent class        returnBase::compute () +M_der; }    Virtual~Derived () {cout<<"Derived deleted"<<Endl; }Private:    intM_der;};classHandler { Public:    //default constructorHandler (): PBase (NULL), use (New int(1)) { }    //General ConstructorsHandler (ConstBase &item): PBase (Item.clone ()), use (New int(1)) { }    //copy Constructor//The reference count is added 1 per copyHandler (ConstHandler &ref): PBase (ref. PBase), use (ref. Use) {        ++*Use ; }    //Overloaded assignment operatorHandler &operator=(ConstHandler &Right ) {        ++*(Right.use);        Decrese_use (); PBase=right.pbase; use=Right.use; return* This; }    //Overloaded arrow operator    ConstBase *operator()Const {        if(pbase)returnpbase; Else            ThrowLogic_error ("Unbound handler!"); }    //Overloaded dereference operators    ConstBase &operator* ()Const{        if(pbase)return*pbase; Else            ThrowLogic_error ("Unbound Handler"); }    voidPrint_use () {cout<< Pbase->getname () <<"Use :"<< *use <<Endl; }    // Destructors~Handler () {decrese_use (); }Private:    //pointers must be used here to ensure that a base instance corresponds to only one reference count    int*Use ; Base*pbase; voidDecrese_use () {if(--*use = =0) {cout<< Pbase->getname () <<"is going-be deleted!"<<Endl; Deletepbase; }    }};intMain () {Handler H1 (Base (2,"Base"));    H1.print_use (); cout<<"Base Compute:"<< (*H1). Compute () <<Endl;    Handler H2 (H1);    H2.print_use (); cout<<"Base Compute:"<< (*H2). Compute () <<Endl; cout<<"-------------------------------------"<<Endl; Handler H3 (Derived (3,"derived",3)); H1=H3;    H1.print_use (); cout<<"Derived Compute:"<< (*H1). Compute () <<Endl; cout<<"system Automatic Delete begin"<<Endl; return 0;}
Second, handle class

The handle class handle has 3 constructors: The default constructor, the copy constructor, and the constructor that receives the base class base object. To ensure dynamic invocation when copying concrete objects in the constructor of the base class base Object , we get the correct class instances, we define the virtual function clonein the class.

Base

Virtual Const {        returnnew Base (*this);}

Derived

Virtual Const {        returnnew Derived (*this);}
Iii. Results of operation

Main function Call:

intMain () {Handler H1 (Base (2,"Base"));    H1.print_use (); cout<<"Base Compute:"<< (*H1). Compute () <<Endl;    Handler H2 (H1);    H2.print_use (); cout<<"Base Compute:"<< (*H2). Compute () <<Endl; cout<<"-------------------------------------"<<Endl; Handler H3 (Derived (3,"derived",3)); H1=H3;    H1.print_use (); cout<<"Derived Compute:"<< (*H1). Compute () <<Endl; cout<<"system Automatic Delete begin"<<Endl; return 0;}

Output:

Base Constructor called! Base Constructor called! Base copy calledbase deletedbase use:1base compute:4base use:2base use:2base compute:4-------------------------------- -----Base Constructor called! Derived Constructor Calledbase Constructor called! Derived constructor calledderived copy calledderived deletedbase deletedderived use:2derived use:2derived Compute:12sys TEM Automatic Delete Beginbase is going to be deleted! Base deletedderived is going to be deleted! Derived Deletedbase deleted

The main function uses the base object to create the handler object H1, and the handler object H2 is constructed by H1, and the output lets you see that the reference count of the handler object is changed from 1 to 2. It then uses the derived object to create the handler object H3, assigns it to H1, and outputs its reference count to H1,h3, which indicates that the reference count is 2.

C + + handle class

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.