Exercise 5.6

This forum is to discuss the book "C++ design patterns and derivatives pricing."

Exercise 5.6

Postby akbar » Fri Nov 26, 2010 6:48 pm

This problem deals with the creation of a reference counted, templatized wrapper class. My main difficulties are related to the issues of counter initialization and sharing.

One of the two usual approaches for creating such a class involves to extend the pointee object class such that includes a counter as an extra member. The "one-object, one counter" association is trivially solved with this approach and the reference counted wrapper is pretty straightforward in that case. This approach is commonly used in most of the literature, but it is not the one suggested by the problem here.

The other approach is to define a pointer to a counter as member of the wrapper class. When a wrapper object is first created, it initializes the value and address of the counter, such that all future instances of wrappers to the same object will simply update the shared counter appropriately. This seems to be the solution suggested here.

I need help for the following issues:
- When a wrapper is created out of an object (or a raw pointer to it), how is it possible for it to know if the counter has already been created and what is its value? If it creates a new pointer to a new counter, we could end up with two wrappers deleting the same object. Do the singleton and factory patterns help in that case, and how?

- Alternatively, one could (for a first instance of wrapper) create the counter out of the object and forbid any future creation of wrapper out of the object itself, but only through copy construction or assignment. This would ensure it gets the counter location and value from an already existing wrapper object. But how do you do this, if it is even possible?

-Even if the wrapper is not templatized, a static counter member of the wrapper class would not work as wrappers pointing to different objects would share the same counter. Does the use of a static member or (global) variable would be of any help here?

I'm pretty much lost to be honest, as the details for implementing such an approach are rather scarce, even in the "Modern C++ Design" reference. An example of implementation would be extremely helpful.
Thanks in advance for your help.
akbar
 
Posts: 28
Joined: Fri Aug 10, 2007 7:12 pm

Re: Exercise 5.6

Postby mj » Wed Dec 01, 2010 2:32 am

well, boost::shared_ptr would be the obvious thing to look at.

My instinct is to create a public class and a private class:

publicshared_ptr: points to a privateshared_ptr

privateshared_ptr :: contains the pointer to the inner object and an integer

the private class would only be accessible to publicshared
mj
Site Admin
 
Posts: 1380
Joined: Fri Jul 27, 2007 7:21 am

Re: Exercise 5.6

Postby emza0114 » Wed Feb 06, 2013 12:31 pm

Hi,

I have attempted to come up with a different approach to yours mj, which is basically a slight modification to the Wrapper class.
Specifically, it simply copies DataPtr and increments an integer which the class stores a pointer of. I am however having trouble in getting it to work properly I have pasted the class below, any help would be much appreciated
cheers
Mark

Code: Select all
//
//
//                              SharedWrapper.h
//
//

#ifndef SHARED_WRAPPER_H
#define SHARED_WRAPPER_H

template< class T>
class SharedWrapper
{
public:
    SharedWrapper()
    {
     DataPtr =0;
     CounterPtr= new int(0);
   }

    SharedWrapper(const T& inner)
    {
      DataPtr = inner.clone();
      CounterPtr = new int(1);
    }

    ~SharedWrapper()
    {
      (*CounterPtr)--;
      if (DataPtr !=0 & (*CounterPtr)==0){
            delete DataPtr;
         delete CounterPtr;
      }
    }
 
    SharedWrapper(const SharedWrapper<T>& original)
    {
        if (original.DataPtr !=0){
            DataPtr = original.DataPtr;
         (*CounterPtr)++;
      }
        else
         DataPtr=0;
    }
   
    SharedWrapper& operator=(const SharedWrapper<T>& original)
    {
        if (this != &original)
        {
            if (DataPtr!=0)
                delete DataPtr;

            if(original.DataPtr !=0){
            DataPtr = original.DataPtr;
            (*CounterPtr)++;
         }
         else
            DataPtr=0;
        }

        return *this;
    }


    T& operator*()
    {
        return *DataPtr;
    }

    const T& operator*() const
    {
        return *DataPtr;
    }

    const T* const operator->() const
    {
        return DataPtr;
    }

    T* operator->()
    {
        return DataPtr;
    }

private:
    T* DataPtr;
   int* CounterPtr;
};
#endif
emza0114
 
Posts: 8
Joined: Sun Nov 25, 2012 2:26 am

Re: Exercise 5.6

Postby mj » Wed Feb 06, 2013 9:12 pm

it seems to me that in

SharedWrapper(const SharedWrapper<T>& original)

counterPtr is not initialized.

More generally, your design is intrusive that is it requires the class to have a clone method whereas one can do a shared pointer class without this.
mj
Site Admin
 
Posts: 1380
Joined: Fri Jul 27, 2007 7:21 am

Re: Exercise 5.6

Postby emza0114 » Thu Feb 07, 2013 9:54 am

Hi mj,

thanks for spotting the first error that stopped my code from crashing.
On you second point when I first attempted this problem my thinking was along these lines, but I had two issues with this approach:

1) By not using clone this seem like the SharedWrapper object does not "own" what it points to. For this to be the case wouldnt you always need to create a clone when ever the constructor is called and only share the object when the copy constructor and assignment operator are called?

2) Ignoring the first point, if I attempt to get rid of clone by simply assigning the address of the inner object
Code: Select all
DataPtr = &inner;

the compiler complains because inner is cast as const and so I get the error 'const StatisticsMC*’ to ‘StatisticsMC*’
If I remove this obviously I get no compalints but then I would be violating one of your rules that you mentioned in an earlier chapter in that I would have two objects which are not independent of each other.

thanks again
Mark
emza0114
 
Posts: 8
Joined: Sun Nov 25, 2012 2:26 am

Re: Exercise 5.6

Postby mj » Fri Feb 08, 2013 2:20 am

well most shared pointer classes take in a raw pointer to the object and then claim ownership of the pointed to object thereafter.
mj
Site Admin
 
Posts: 1380
Joined: Fri Jul 27, 2007 7:21 am


Return to C++ design patterns and derivatives pricing

Who is online

Users browsing this forum: No registered users and 1 guest

cron