C ++ Primer study note _ 83 _ templates and generic programming

Source: Internet
Author: User

Template and generic programming-a generic handle class



Introduction:

[Careful mine]

This example shows that C ++ is a complex language application and needs to be well understood to understand it.InheritanceAndTemplate. It may be helpful to study this example after you are familiar with these features. On the other hand, this example can well test your understanding of these features.



The use of the Sales_item and Query classes in the preceding exampleThe implementation is the same. This type of problemVery suitable for generic programming:CustomizableClass template management pointer and usage count. Originally unrelated Sales_item and Query types can be simplified by using this template for public counting. As a result, the inheritance layers of lower layers are disclosed or hidden, and the handles can be different.



I. Define the handle class

Handle class behavior is similar to pointer:CopyHandleObjectSetBasic object will not be copied, After copying, the two Handle objectsReference the same basic object. To create a Handle object, you must pass the address of the dynamically allocated object of the type managed by Handle (or derived from this type). From now on, handle will "own" this object. In addition, once no Handle object is associated with this object,HandleClass will be responsible for deleting this object.

HandleClass:

template <class T> class Handle{public:    Handle(T *p = 0):ptr(p),use(new size_t(1)) {}    Handle(const Handle &h):ptr(h.ptr),use(h.use)    {        ++ *use;    }    Handle &operator=(const Handle &rhs);    ~Handle()    {        rem_ref();    }    T &operator*();    T *operator->();    const T &operator*() const;    const T *operator->() const;private:    T *ptr;    size_t *use;    void rem_ref()    {        if (-- *use == 0)        {            delete use;            delete ptr;        }    }};


Value assignment operator:

template <class Type>Handle<Type> &Handle<Type>::operator=(const Handle<Type> &rhs){    ++ *rhs.use;    rem_ref();    ptr = rhs.ptr;    use = rhs.use;    return *this;}

Unreference operators and member access Operators[+ P562Exercise16.45]:

If Handle is not bound to an object, an exception is thrown when you attempt to access the object:

template <typename Type>Type &Handle<Type>::operator*(){    if (ptr)    {        return *ptr;    }    throw std::runtime_error("dereference of unbound Handle");}template <typename Type>Type *Handle<Type>::operator->(){    if (ptr)    {        return ptr;    }    throw std::runtime_error("access through unbound Handle");}template <typename Type>const Type &Handle<Type>::operator*() const{    if (ptr)    {        return *ptr;    }    throw std::runtime_error("dereference of unbound Handle");}template <typename Type>const Type *Handle<Type>::operator->() const{    if (ptr)    {        return ptr;    }    throw std::runtime_error("access through unbound Handle");}

Ii. Handle

We hope that the Handle class can be used in the internal implementation of other classes.

A simple example: assign an int object and bind a Handle object to the newly allocated int object to demonstrate Handle's behavior:

{    Handle<int> hp(new int(42));    {        Handle<int> hp2 = hp;        cout << *hp << " " << *hp2 << endl; //42 42        *hp2 = 10;    }    cout << *hp << endl;    //10}

Even if the Handle user is assigned an int object, the Handle destructor will delete it. When the last Handle object at the end of the outer code is out of scope, delete the int object.

UseHandleObject used to count the pointer

You can re-implement the Sales_item class and use Handle in the class. This version of this class defines the same interface, but you can delete the copy control member by replacing the Item_base pointer with the Handle <Item_base> object:

class Sales_item{public:    Sales_item():h() {}    Sales_item(const Item_base &item):h(item.clone()) {}    const Item_base &operator*() const    {        return *h;    }    const Item_base *operator->() const    {        return h.operator -> ();    }private:    Handle<Item_base> h;};

Because this version of Sales_item does not have pointer membersNoCopy control Member, This version of Sales_item can safely use the merged copy control member. The work of managing the use of counting and related Item_base objects is completed in Handle.

Because the interface is not changed, you do not need to change the code of using the Sales_item class. For example:

double Basket::total() const{    double sum = 0.0;    for (const_iter iter = items.begin();            iter != items.end();            iter = items.upper_bound(*iter))    {        sum += (*iter)->net_price(items.count(*iter));    }    return sum;}

Analysis:

        sum += (*iter)->net_price(items.count(*iter));

1) (* iter) returns h, which is a member using a counter handle;

2) Therefore, (* iter)-> use the overload arrow operator of the handle class;

3) the compiler calculates h. operator-> () and obtains the Item_base pointer saved by the Handle object;

4) the compiler unreferences the Item_base pointer and calls the Item_base Member of the object to which the Pointer Points.

// P564 exercise 16.51 class Query {friend Query operator ~ (Const Query &); friend Query operator | (const Query &, const Query &); friend Query operator & (const Query &, const Query &); public: query (const string &); set <TextQuery: line_no> eval (const TextQuery & t) const {return h-> eval (t );} ostream & display (ostream & OS) const {return h-> display ();} private: Query (Query_base * query): h (query) {} Handle <Query_base> h ;};/*** other operations are similar to the previous operations. Do not repeat them here */

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.