Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

extending shared_ptr by inheritance

What is so bad about doing something like this?

class myclass : public std::shared_ptr<myotherclass> {
     // some code,  an allocation is never done
     std::string get_info () {
          if(*this != nullptr) return "<info>" + (this->info * 3) + "</info>";
          else return "";
     }
 };

when no allocation is done in the class --- it is just to provide some decoration like above?

like image 994
ribamar Avatar asked May 18 '15 17:05

ribamar


2 Answers

I would suggest using std::enable_shared_from_this<> and then this->shared_from_this().

like image 170
Doug Royer Avatar answered Nov 07 '22 19:11

Doug Royer


Since you will never manually delete it (and you should never manually delete anything, which is rather the point of shared_ptr in the first place), virtual destructors aren't really an issue.

Some interoperability problems may come up, though.

  1. You only get your derived class when you create specific instances of it. When you get a shared_ptr from somewhere like get_shared_from_this, it won't include your info.

  2. Function templates overloaded on shared_ptr<T> won't see the inheritance. Your derived class will suddenly appear foreign to random functions such as std::static_pointer_cast.

Fortunately, the C++ standard library is full of neat extensibility hooks. You can install a custom deleter like so:

template< typename t >
struct my_deleter
    : std::default_delete< t > {
    std::string info;

    my_deleter( std::string in_info )
        : info( std::move( in_info ) ) {}
};

std::shared_pointer< foo > myfoo( new foo, my_deleter{ "it's a foo" } );

and retrieve the info with a non-member function:

template< typename t >
std::string get_my_info( std::shared_ptr< t > ptr ) {
    my_deleter< t > * dp = std::get_deleter< my_deleter< t > >( ptr );
    if ( ! dp ) return {};
    return dp->info;
}

This isn't a very good program architecture, since there's only one custom deleter slot per shared object. It can do in a pinch, though.

like image 20
Potatoswatter Avatar answered Nov 07 '22 20:11

Potatoswatter