user1040229
user1040229

Reputation: 501

C++ boost::shared_ptr as a member of a class and repeatedly setting its value

I am trying to figure out the cleanest way to implement using a boost::shared_ptr as a member of a class. Let's say I have class A that contains a boost::shared_ptr to a class B member. The B class could be either the base type (B) or a derived type (let's say C or D). This member would be obtained/set continuously throughout the lifetime of class A (using accessors/modifiers). B has to be polymorphic so I can't just store it as B but rather as a reference/pointer to B. I also wanted to avoid having to manage the memory on my own as well. Let's say it all looked like:

class A
{
public:
    const B& GetB() const { const B* b = m_pB.get(); return *b; } // Is the correct way to do this?
    void SetB(const B& b) { B* b = m_pB.get(); *b = b; } // Is the correct way to do this?

private:
    boost::shared_ptr<B> m_pB;
};

I know I'm probably doing something wrong but I wanted to provide an example of what I'm trying to accomplish. Thanks!

Upvotes: 2

Views: 1272

Answers (2)

bcsanches
bcsanches

Reputation: 2372

In your setter, you are assigning the new data to the existing element, not updating the pointer.

The correct way would be:

void SetB(shared_ptr<B> ptr)
{
     m_pB = ptr;
}

So doing this you will be transferring the ownertship of the object to the class. For using, you would write code like:

A a;

shared_ptr<B> ptrB(new C()); //or new D, whatever
a.SetB(ptrB);

Another option, if the code thats creates B does not use shared_ptr at all and the shared_ptr will be encapsulated inside your class, is to change the setter to get a pointer to B, like:

void SetB(B *pB)
{
     m_pB.reset(pB);
}

In the end, if this last sample is what you need and the shared_ptr will be restricted only to the class A, I would sugest using scoped_ptr instead of shared_ptr.

Upvotes: 0

John Humphreys
John Humphreys

Reputation: 39294

I think this program's design needs rethinking.

The purpose of a shared pointer is that you leave the dynamically allocated resource within it so that it manages the life-cycle of that resource. If you're changing what's in there, then you're responsible for managing the life of that resource after you replace the pointer in there and that's going to lead to confusion.

You should probably just assign over the m_pB variable with a new shared pointer so the original one goes out of scope and frees the resource that was being held in the first place. So, assign over the shared pointer, not over the pointer it holds.

Upvotes: 1

Related Questions