minicaptain
minicaptain

Reputation: 1216

SmartPtr and template

As we knew, In order to avoid memory leak, we had better to use SmartPtr to managing the object instead of common pointer.

In most cases, it works very well.

Now I have encountered a problem, I tried my best to describe it more simply.

I have a base class:

class Base;

I have another two classes inherited from base class:

class Derive1 : public Base;

class Derive2 : public Base;

If I use raw pointer, I can implement polymorphic easily;

Base *pd1 = new Derive1();

Base *pd2 = new Derive2();

But If I want to use smartPtr to implement the same thing how should I to do? For example:

SmartPtr<Base> pd1 = SmartPtr<Derive1>(new Derive1);

Is there smartPtr to support the transformation, or shall I need to implement a template of smartPtr, but If I implement the template by myself, how to avoid the code bloating,who has good advice?

If there is a template smartPtr supporting this operation, how do it accomplish this function? as we know a base pointer can point to a derived object, but it is bad in turn!!

Upvotes: 1

Views: 855

Answers (4)

Felix Glas
Felix Glas

Reputation: 15524

You don't need to implement your own smart pointer template, use std::unique_ptr or std::shared_ptr.

For example, this will work just the way you want, exploiting polymorphic behaviour.

std::unique_ptr<Base> sptr1{new Derive1()};
std::unique_ptr<Base> sptr2{new Derive2()};

That is, you can use sptr1 & sptr2 in the same way as:

Base* pd1 = new Derive1();
Base* pd2 = new Derive2();

When sptr1 & sptr2 goes out of scope then the destructor Base::~Base() will be called and the internal pointer to the Base-object will be deleted. Make ~Base() virtual to also call ~Derive1() and ~Derive2() respectively, upon destruction (same as you would do without the smart pointer).

Live example: http://ideone.com/zVebLV

To make sptr1 point to another derived object do like this:

sptr1 = sptr2; // This will destruct previous object pointed to by sptr1.
               // Will also set sptr2 = nullptr.

More info about smart pointers: C++11 Smart Pointer Policies

Upvotes: 1

Roddy
Roddy

Reputation: 68033

I think you're asking 'how should this line code work?'?

SmartPtr<Base> pd1 = SmartPtr<Derive1>(new Derive1);

The best advice I have is to look at boost or similar source for shared_ptr. Basically it uses a templated constructor, allowing you to construct one shared pointer from another. Obviously the underlying pointer types have to be compatible...

template<class Y> shared_ptr( shared_ptr<Y> const & r )
: px( r.px ), pn( r.pn ) 
{
}

Of course, you could avoid this, by just writing this instead in the first place:-

SmartPtr<Base> pd1(new Derive1);

Upvotes: 1

cdmh
cdmh

Reputation: 3344

Destroying the object will work correctly, so long as you have a virtual destructor in Base:

class Base {
  public:
    virtual ~Base();
    ...
};

Upvotes: 4

Seth Carnegie
Seth Carnegie

Reputation: 75130

If you're talking about std::shared_ptr<T> or unique_ptr<T>, then yes, it will handle that case because internally it stores data of the type T*, in this case Base*. So you are fine using it that way. They wouldn't be of much use otherwise.

Upvotes: 1

Related Questions