Reputation: 1216
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
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
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
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
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