Click to See Complete Forum and Search --> : Deriving from shared_ptr


paradoxresolved
May 4th, 2008, 12:50 PM
Is it safe to publicly derived from shared_ptr? I don't see a virtual destructor. . .

laserlight
May 4th, 2008, 01:33 PM
No, the lack of virtual members functions and a non-virtual destructor show that shared_ptr is not intended to be a base class.

STLDude
May 4th, 2008, 02:05 PM
Also, I would ask what functionality you perceive you need to derive new class from it?
If it's has something to do with deletion of an object, shared_ptr already prides option to use your custom deleter.

paradoxresolved
May 5th, 2008, 12:29 PM
I was toying around with the idea of a derived version of the shared_ptr that automatically dynamically allocated space using a default contructor of the object is pointed to. That way I could write:

myshared_ptr<MyClass> pMyClass;

instead of. . .

shared_ptr<MyClass> pMyClass(new MyClass);

The idea was to make my code a little less cluttered.

Oh well.

jlou
May 5th, 2008, 05:58 PM
If you wanted to you could achieve the same thing through composition or private inheritance.

paradoxresolved
May 5th, 2008, 06:32 PM
Why is private inheritance different?

What do you mean by composition?

jlou
May 5th, 2008, 06:47 PM
Public inheritance is generally meant to be used to implement polymorphic behavior. It models "is-a" or "works-like-a". In other words, you have code that works on a base class pointer or reference, and virtual functions allow derived classes to specialize the work done by the functions that are called.

Private inheritance is used for "has-a" or "is-implemented-in-terms-of". It is a way of implementing a class in terms of another class. Composition is another way of doing this which is usually preferred, but there are a few cases in which private inheritance makes more sense. Composition just means making a member variable out of the other class:template<typename T>
class myshared_ptr
{
shared_ptr<T> p;
public:
myshared_ptr() : p(new T) { }

// add forwarding functions here.
};

See this FAQ for more information: http://www.parashift.com/c++-faq-lite/private-inheritance.html#faq-24

paradoxresolved
May 5th, 2008, 07:37 PM
I know what private inheritance is, but I'm not sure how it gets around the 'no virtual destructor' problem. It also presents the problem of hiding the shared_ptr<T> interface. I'd prefer not to bother access declarations to get around this.

*sigh* I think this might be more work than necessary at the moment. Thanks for the suggestion anyway.

jlou
May 5th, 2008, 07:43 PM
It gets around the problem because code that uses your class cannot attempt to use it polymorphically, and specifically cannot delete it through a pointer to the base shared_ptr class.

Admittedly, this will probably not be a problem for you, since I doubt a shared_ptr is allocated with new anyway. However, using one of the other two alternatives is not a lot of work and makes your design intent clearer. Since shared_ptr has a relatively small and defined interface, I don't think it would be that hard to add forwarding functions (or using statements if you use private inheritance).

I honestly don't know whether it is a good idea to make your own smart pointer just for the minor convenience of simpler construction, but it isn't that hard if you really wanted to.

exterminator
May 6th, 2008, 11:16 AM
I have a feeling you need a factory function returning a shared_ptr. But I also have a feeling that you are uselessly wondering about saving some typing via artificial ways. The derivation from shared_ptr for the use case you provided is not very good/useful. But if the object creation is complex or you need to do some fancy stuff with the created object you might choose a creational pattern to save yourself the same typing repeatedly and avoiding the complexity by keeping it at one place and reducing chances of bugs/different behavior.