Boost logo

Boost Users :

From: Taneli R. (the_vizitor_at_[hidden])
Date: 2007-10-02 08:12:41


I'm converting pipes and filters architecture made with raw pointers to use
shared_ptrs. My Pipe class has a static counter, which gives unique pipeID
to every pipe. Since Pipe class has pure virtual functions, the pipes in my
architecture are instances of derived classes.

Pipe class looks like this:

class Pipe
{
    public:
        Pipe() : pipeID(++pipeCount) {}
        virtual bool lay(boost::shared_ptr<Pipeable>& source, string&
sourceTag, boost::shared_ptr<Pipeable>& destination, string& destTag) = 0;
        /*...other pure virtual functions here...*/
    protected:
        int pipeID;
        static int pipeCount;
}

My problem is that when I try to make a new pipe between source and
destination, the pipe is made twice (with different pipeID-numbers), which
is a problem because there should be only one pipe connecting my components.
I believe it is a result from using "this"-pointer directly without enabling
"shared_from_this". I know that I should use it somehow but the same time I
should maintain the unique pipeID.

If I create a new shared_ptr with "shared_from_this" enabled inside
SimplePipe, it has a different pipeID than the one I should be using. I have
to use shared_ptr because I'm storing pointers into containers. And finally
I cannot instantiate Pipe directly from its base class with using
"shared_from_this" because it has pure virtual functions.

Any help for solving this problem or a decent tutorial on using shared_ptrs
and enable_shared_from_this would be appreciated.

The following code snippets illustrate the problem:

//
//Main
//

boost::shared_ptr<Pipe> pipe;
pipe = inputPipes[tag]; //find a matching pipe from the map

if (pipe.get() == 0) //if not found, create a new pipe
{
    boost::shared_ptr<Pipeable> source; // no source
    boost::shared_ptr<Pipeable> destination
(boost::dynamic_pointer_cast<Pipeable>(comp));
                                             
    pipe = boost::shared_ptr<Pipe>(new SimplePipe(source, srcTag,
destination, destTag)); //creating new pipe
   
    inputPipes[tag] = pipe; //put the pipe into a map
}

//
//SimplePipe, derived from Pipe
//

SimplePipe::SimplePipe(boost::shared_ptr<Pipeable>& source, string&
sourceTag, boost::shared_ptr<Pipeable>& destination, string& destTag)
{
    lay(source, sourceTag, destination, destTag);
}

bool SimplePipe::lay(boost::shared_ptr<Pipeable>& source, string& sourceTag,
boost::shared_ptr<Pipeable>& destination, string& destTag)
{
        if (source.get() != 0 && destination.get() != 0 &&
!sourceTag.empty() && !destTag.empty()) //Both ends attached
    {
            if (source->makeSource(pipeID, sourceTag))
            {
                this->source = source; //problem?
                if (destination->makeDestination(pipeID, destTag))
                {
                    this->destination = destination; //problem?
                    return true;
                }
                else
                {
                    source->detachPipe(pipeID);
                }
            }
    }
        else if (source.get() == 0 && destination.get() != 0 &&
!destTag.empty()) //only destination attached
    {
        if (destination->makeDestination(pipeID, destTag))
        {
            this->destination = destination; //problem?
            return true;
        }
    }
        else if (source.get() != 0 && destination.get() == 0 &&
!sourceTag.empty())
        {
                /*etc etc...*/
        }
        return false;
}

-- 
View this message in context: http://www.nabble.com/boost%3A%3Ashared_ptr-and-%22this%22-pointer%3A-how-to-use-shared_from_this--tf4554528.html#a12997562
Sent from the Boost - Users mailing list archive at Nabble.com.

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net