Using an abstract deleter with std::unique_ptr - c++

I want to have a run-time interface that offers some creation methods. These methods return unique_ptr<T>, and I want to enable custom deletion by the creating class. The thing is that I definitely don't want the interface to offer these methods directly- they should only be available in the destruction of the unique_ptr<T, SomeCustomDel>. Now, I figured that I can use std::unique_ptr<T, std::function<void(T*)>>, but I'd really rather not because I simply don't need that level of abstraction and I don't want to have to pay the heap allocation.
Any suggestions?

Your specification isn't completely clear to me, but have you considered unique_ptr<T, void(*)(void*)>? This is a very flexible type with many qualities of a dynamic deleter.
If that isn't what you're looking for, you might try something along the lines of:
class impl
{
public:
virtual ~impl();
virtual void operator()(void*) = 0;
virtual void other_functionality() = 0;
};
class my_deleter
{
impl* p_;
public:
...
void operator()(void* p) {(*p_)(p);}
void other_functionality() {p_->other_functionality();}
...
};
It is difficult to know what is best in your case without more details about your requirements.

I wish there was a standard "dynamic" deleter version of std::unique_ptr. This mythical class would allow me to attach a deleter to the unique_ptr when I instantiate it, similar to std::shared_ptr.
That said if such a type existed I suspect it would essentially be implemented with std::unique_ptr<T,std::function<void(T*)>>. The very thing you wanted to avoid.
However I think you're underestimating std::function. Its implementation is optimization to avoid hitting the heap if possible. If your deleter object remains small everything will be done on the stack (I think boost::function can statically handle deleters up to 32 bytes in size).
A for the problem of a too general deleter. You have to provide the definition of the deleter. There is no way around that. However you don't have to let the user instantiate the class, which essentially forbids them from using it. To do this make the deleter's constructor(s) require a tag structure that is only defined in the implementation file.
Or possibly the simplest solution. Put the deleter in a detail namespace. The user is still free to use it, but it's obvious that they should not and can't complain when you change it, breaking their code.

I see two options.
Option 1: Use a custom deleter that contains a function pointer and optionally a raw char array to encode some state if necessary:
template<class T>
void simply_delete(T* ptr, const unsigned char*) {
delete ptr;
}
template<class T, int StateSize>
struct my_deleter {
void (*funptr)(T*,const unsigned char*);
array<unsigned char,StateSize> state;
my_deleter() : funptr(&simply_delete<T>) {}
void operator()(T* ptr) const {
funptr(ptr,StateSize>0 ? &state[0] : nullptr);
}
};
template<class T>
using upi = unique_ptr<T,my_deleter<T,sizeof(void*)>>;
Now, you can create different upi<T> objects that store different function pointers and deleter states without the need of mentioning what exactly is happening in its type. But this is almost the same as a function<> deleter which implements the "small function optimization". You can expect a decent standard library implementation to provide a very efficient function<> wrapper for small function objects (like function pointers) that don't require any heap allocations. At least I do. :)
Option 2: Simply use shared_ptr instead of unique_ptr and make use of its built-in type erasure feature with respect to deleters. This will also allow you to support Derived->Base conversions easily. For greatest control over what is allocated where you could use the std::allocate_shared function template.

This is a response to one of the answers, not to the original question. It is an answer instead of a comment simply because of formatting reasons.
I wish there was a standard "dynamic"
deleter version of std::unique_ptr.
This mythical class would allow me to
attach a deleter to the unique_ptr
when I instantiate it, similar to
std::shared_ptr.
Here is a start of an implementation of such a class. It is fairly easy to do. I've used unique_ptr only as an exception safety aid, nothing more. It is not as full-featured as you might like. These extra features are left as an exercise for the reader. :-) What is below establishes unique ownership of the pointer and storage for the custom dynamic deleter. Note that the smart pointer owns a passed-in pointer even if the constructor of the smart pointer throws (this is actually where unique_ptr is most useful in the implementation).
#include <memory>
#include <type_traits>
namespace detail
{
class impl
{
public:
virtual ~impl() {};
};
template <class T, class D>
class erase_type
: public impl
{
T* t_;
D d_;
public:
explicit erase_type(T* t)
noexcept(std::is_nothrow_default_constructible<D>::value)
: t_(t)
{}
erase_type(T* t, const D& d)
noexcept(std::is_nothrow_copy_constructible<D>::value)
: t_(t),
d_(d)
{}
erase_type(T* t, D&& d)
noexcept(std::is_nothrow_move_constructible<D>::value)
: t_(t),
d_(std::move(d))
{}
virtual ~erase_type()
{
if (t_)
d_(t_);
}
erase_type(const erase_type&) = delete;
erase_type& operator=(const erase_type&) = delete;
};
} // detail
template <class T>
class my_pointer
{
T* ptr_;
detail::impl* impl_;
public:
my_pointer() noexcept
: ptr_(nullptr),
impl_(nullptr)
{}
template <class Y>
explicit my_pointer(Y* p)
: ptr_(static_cast<T*>(p)),
impl_(nullptr)
{
std::unique_ptr<Y> hold(p);
impl_ = new detail::erase_type<Y, std::default_delete<Y>>(p);
hold.release();
}
template <class Y, class D>
explicit my_pointer(Y* p, D&& d)
: ptr_(static_cast<T*>(p)),
impl_(nullptr)
{
std::unique_ptr<Y, D&> hold(p, d);
typedef
detail::erase_type<Y, typename std::remove_reference<D>::type>
ErasedType;
impl_ = new ErasedType(p, std::forward<D>(d));
hold.release();
}
~my_pointer()
{
delete impl_;
}
my_pointer(my_pointer&& p) noexcept
: ptr_(p.ptr_),
impl_(p.impl_)
{
p.ptr_ = nullptr;
p.impl_ = nullptr;
}
my_pointer& operator=(my_pointer&& p) noexcept
{
delete impl_;
ptr_ = p.ptr_;
impl_ = p.impl_;
p.ptr_ = nullptr;
p.impl_ = nullptr;
return *this;
}
typename std::add_lvalue_reference<T>::type
operator*() const noexcept
{return *ptr_;}
T* operator->() const noexcept
{return ptr_;}
};
Note that unlike unique_ptr (and like shared_ptr), the constructors taking a pointer are not noexcept. Although that could possibly be mitigated via the use of a "small deleter" optimization. Yet another exercise left for the reader. :-)

I found this question googling my own problem; using unique_ptr with an abstract base class pointer. All the answers are great. I found #deft_code's one to be the best for my needs.
This is what I ended up doing in my case:
Suppose T is an abstract base class type. The makeT(), func creates a new instance of some derived class, and returns the T*:
std::unique_ptr<T, std::function<void(T*)>> p(makeT(), [](T* p){p.delete();});
I just wanted to share this for those who are looking for short, copy and pasteish solution.
For the untrained c++11 eyes, the [](... syntax is a lambda.
As is mentioned in the other answers, it's not a 'function pointer' in the C sense, but a callable c++ object, which is really tiny, and should have negligible overhead to carry it around.

Related

Implicit downcast of shared_ptr in CRTP

I built a class Interface to be used with CRTP for static polymorphism and a Client class having a shared_ptr to the Interface. I would like to return from the Client the shared_ptr to the Implementation, something that I can (safely?) do through static_pointer_cast within the Client. Is there a way to allow an implicit downcasting from the shared_ptr to Interface to a shared_ptr to Implementation?
template<class Implementation>
struct Interface {
int foo() { return static_cast<Implementation*>(this)->fooimpl();}
};
template<class Implementation>
struct Client {
Client(std::shared_ptr<Implementation> const & pt) : pt_{pt} {}
std::shared_ptr<Interface<Implementation>> pt_;
std::shared_ptr<Implementation> getPt() {
//Can I avoid this static_pointer_cast?<
return std::static_pointer_cast<Implementation>(pt_);
}
};
One possible solution to avoid all this mess is to keep a shared_ptr to Implementation within the Client class. In this way, however, nowhere I am saying that Implementation in Client has the Interface.
template<class Implementation>
struct Client {
Client(std::shared_ptr<Implementation> const & pt) : pt_{pt} {}
std::shared_ptr<Implementation> pt_;
std::shared_ptr<Implementation> getPt() { return pt_;}
};
Is there a way to allow an implicit downcasting from the shared_ptr to Interface to a shared_ptr to Implementation?
Simple answer: No! As the compiler have no idea of the "reverse" inheritance, it can give you direct support for it. CRTP is a general pattern to work around the underlying problem. Here the downcast is hand coded but hidden behind the interface of the CRTP implementation.
The CRTP is because I want Client to use foo() and at the same time independent of the implementation
As you get it as a compile time implementation, it is not really independent at the moment. You will see it latest, if you want point to something of that CRTP type.
The shared_ptr is because the Implementation may be shared among Clients
Your idea have a circular problem!
If you write as given in your example:
template
struct Client {
Client(std::shared_ptr const & pt) : pt_{pt} {}
std::shared_ptr pt_;
std::shared_ptr getPt() { return pt_;}
};
the code which calls getPt() must know the type of the returned pointer! Even if you use auto you will get the type of the returned pointer. So you simply can't hide it from your using code at all.
I ended up just putting a shared_ptr to the Implementation as class member and added a "static_assert + is_base_of " to insure this.
Seems to be also a circular problem.
If you write:
template < typename T>
class CRTP: public T
{
public:
void Check()
{
static_assert( std::is_base_of_v < T, CRTP<T> > );
}
};
class A {};
int main()
{
CRTP<A> x;
x.Check();
}
What is the assert helping here? It is only a check that you wrote 4 lines above "class CRTP: public T". For me that makes no sense.
I still have no real idea what you want to achieve more than simply using CRTP.

Any reason behind the syntax difference between shared pointers and unique pointers with custom deleters

While both shared pointers and unique pointers in C++11 allow user defined deleters, they have notable syntax differences, as shown in the below mini example:
#include "pch.h"
#include <memory>
class factory
{
public:
static factory * create() {
return new factory();
}
static void destroy(factory* fp) noexcept{
delete fp;
}
factory(const factory &) = delete;
factory& operator= (const factory &) = delete;
private:
char * p_;
factory() {
p_ = new char[100];
}
~factory() {
delete[] p_;
}
};
int main()
{
typedef void(*fp)(factory*);
auto del = [](factory * p) noexcept {
factory::destroy(p);
};
std::shared_ptr<factory> fsptr1(factory::create(), del);
std::shared_ptr<factory> fsptr2(factory::create(), del);
//notice the syntax is different
std::unique_ptr<factory, fp> ufsptr1(factory::create(), del);
std::unique_ptr<factory, decltype(del)> ufsptr2(factory::create(), del);
return 0;
}
The reason behind this is that the template class for shared pointers is defined as
template< class T > class shared_ptr;
and the template class for unique pointers is defined as
template<class T, class Deleter = std::default_delete<T>> class unique_ptr;
My question is: Is there any reason behind this design decision that the syntax of the two differentiates itself from each other? My naive thinking is that if the template class for shared pointers is made as
template< class T, class Deleter = std::default_delete<T>> class shared_ptr;
it will makes more sense. For one thing, it is consistent with the case of unique pointers, and for another, it won't instantiate when the default deleter is not well formed and the user fails to provide a custom one.
The default std::unique_ptr is only storing one element, the pointer to the data it protects. This is because by default, you want to use the least amount of memory possible. But when you specify a deleter, you need also to store it. So you need to differentiate between the two versions.
See here: https://github.com/llvm-mirror/libcxx/blob/master/include/memory#L2397
The storage is a specific type based on the template types.
But for std::shared_ptr, you don't have this constraint, you already have a counter, you need to allocate a block to store it. So you can make the deletion choice inside the allocation logic instead of outside, at the API level.
See here: https://github.com/llvm-mirror/libcxx/blob/master/include/memory#L3592
The compressed_pair is not in the smart pointer itself, but in the allocated block.

Deleting a Template Type

I have a generic class that looks something like this:
template <class T>
class Example
{
private:
T data;
public:
Example(): data(T())
Example(T typeData): data(typeData)
~Example()
// ...
};
I'm a bit confused about how to implement a deconstructor for something like this. Specifically, since T is of any type, it could be memory allocated on the stack (which is always the case for Example's created via the no-argument constructor) or on the heap.
For instance, if the client makes the type for T an int* and provides a pointer to dynamic memory, how do I know to call delete on data as opposed to if the client set the type to int?
The simplest answer is: don't. Don't try to second-guess the user and do something they might not expect. Adopt the same policy as standard containers do: assume T cleans up after itself correctly.
If the client code is written correctly, it will use RAII classes (such as smart pointers) for automatic and correct management of memory and other resources. If it's not, you cannot hope to fix that in your provider code.
Make your class work with std::unique_ptr and std::shared_ptr, as well as any other custom RAII class, and let your clients do the management themselves. What if they want to store non-owning pointers, after all?
You can use Template Specialization.
template <class T>
class Example
{
private:
T data;
public:
Example()
: data(T())
{}
Example(T typeData): data(typeData)
{}
};
template <class T>
class Example<T*>
{
private:
T* data;
public:
Example() : data(nullptr){}
Example(T* typeData): data(typeData) {}
~Example()
{
delete data;
}
};
int main()
{
Example<int> e;
Example<int*> e2;
return 0;
}
You could just not worry about it like the standard library does. For example, if you create a vector of pointers you are responsible for deleting them before you let the vector go out of scope. People can then decide if they even want it to be deleted at all (maybe it's temporary for sorting and something else owns the object). They can also use smart pointers so that vector will destroy the object via the destructor for the smart pointer.
In this case, less is more. You don't have to do anything complicated. You don't have to maintain multiple versions of the template. Finally, the user of your template has more control...and responsibility as well of course.
Use memory release helper template classes that can be selected by type.
You does not need to make dublicate of your class with Template Specialization.
You can write only one class.
#include <type_traits>
template<typename T> // primary template
struct Releaser
{
template<typename V>
void release( V v ) { }
};
template<> // explicit specialization for T = std::true_type
struct Releaser<std::true_type>
{
template<typename V>
void release( V v ) { delete[] v; }
};
template <class T>
class Example
{
private:
T data;
public:
Example(): data(T()) {}
Example(T typeData): data(typeData) {}
typedef typename std::is_pointer<T>::value_type isptr_type;
~Example() {
Releaser< isptr_type >::release( data );
}
};
But need to know form of new called, so use delete or delete[].
I suggest you to use std::unique_ptr for T when you need Example to hold an owning pointer. If T is a raw pointer, then it's simply not owning and should not delete it.
If you need Example to initialize the pointer, specialize it for std::unique_ptr and call std::make_unique in the default constructor.
template<typename T>
class Example<std::unique_ptr<T>> {
Example() : data{std::make_unique<T>()} {}
/* rest of the class */
};
If you do this, you should not specialize your class for T* to do a new, as you cannot initialise non-owning pointers. You should receive it in you constructor, and maybe disable the default constructor for raw pointers if you don't want it to be null.
template<typename T>
class Example<T*> {
Example() = delete;
Example(T* data_) : data{data_}
/* data is not an owning pointer. No need for a destructor */
/* rest of the class */
};
If you follow those rules, you should have no problem with memory management.

Template class issues

I am having the following problem. Consider this (very simplified) example. I am using one of our existing template classes that I am able to add (up to a point) some generic functionality to:
template<typename T> class myClass
{
public:
typedef T element_type;
explicit myClass(T* p = 0) : ptr(p) {}
~myClass() { delete ptr; };
......
private:
T* ptr;
};
I am also using an external library (which I am obviously not able to adjust) which amongst other things defines (lets say) struct notMine. As this is a C style library, one does some sort of notMine* nmPtr = createNotMine(); call and I need to remember to freeNotMine(nmPtr); when I am done.
Now I want to use myClass with a pointer to a notMine structure but the problem is that when myClass goes out of scope, I 'forget' to free this notMine structure and it calls 'delete' instead.
What is a nice way of fixing this problem?
Do I create class derived from myClass where I can write my own destructor specific to this problem?
Do I adjust myClass so I can pass some sort of optional generic Destructor object?
Do I adjust myClass so I can (optionally) pass a static function that is to be called in the destructor?
EDIT: I probably didn't explain myself properly, but the myClass is already being used elsewhere, so I cannot simply change the existing destructor to suit this particular problem
For you immediate implementation
Given than the class can be modified (maintaining backwards compatibility), you can extend the class to include a custom deleter to manage the resource (with a suitable default). Custom deleters can then be implemented for each type that the class needs to maintain.
template <typename T>
struct DefaultDeleter {
void operator()(T* ptr) const {
delete ptr;
}
}
struct NotMineDeleter { // or a specialisation of DefaultDeleter
void operator()(notMine* nmPtr) const {
if (nmPtr)
freeNotMine(nmPtr);
}
}
template<typename T, typename Deleter = DefaultDeleter<T> >
class myClass
{
public:
typedef T element_type;
explicit myClass(T* p = 0) : ptr(p) {}
~myClass() { deleter_(ptr); };
......
private:
Deleter deleter_;
T* ptr;
};
The myClass can now be used as follows for the external library;
myClass<notMine, NotMineDeleter> obj(createNotMine());
You will also need to deal with the copy and assignments for your class myClass by either making them private: (C++03), deleting them =delete; (C++11) or implementing the appropriately, i.e. implement the full copy and assignment semantics.
You've commented that the copy and assignments are implemented appropriately (this will need to be the case for the notMine* pointers as well). If this is not the case, then you will probably run into further problems.
C++11 also brings with it move semantics that can be implemented to transfer ownership from one instance of myClass to another.
Better yet
Use std::unique_ptr or std::share_ptr with a custom deleter that calls freeNotMine(nmPtr).
RAII - what it looks like you are doing is implementing a classic RAII class. This is a very good thing and one of the core idiomatic uses of resource classes in C++.
Alternative to the dual deleter above
Using template specialisation, the implementation can be simplified (but essentially still maintains deleters for each type being maintained) as follows;
template <typename T>
struct Deleter {
void operator()(T* ptr) const {
delete ptr;
}
}
template <>
struct Deleter<notMine> {
void operator()(notMine* nmPtr) const {
if (nmPtr)
freeNotMine(nmPtr);
}
}
template<typename T>
class myClass
{
public:
typedef T element_type;
explicit myClass(T* p = 0) : ptr(p) {}
~myClass() { deleter_(ptr); };
......
private:
Deleter<T> deleter_;
T* ptr;
};
The myClass can now be used as follows for the external library;
myClass<notMine> obj(createNotMine());

Retaining functors as variables

I'm working on a resource management class and want to have the user provide a functor to a "ReleaseResource" method as part of the resource manager's constructor. From there when a resource is requested that functor will be provided as the deleter for the shared_ptr that I will be returning so that the appropriate method will be called when the resource is no longer used.
The problem I'm running into that this requires me to store the functor in my class, and I'm not entirely sure how to do that. Typically when using a functor you template the function like so:
template<class MyFunctor> MyMethod(MyFunctor f) {
f();
}
Which is great if you intend to use the functor in the scope of that function, but since the template goes out of scope with the function I'm not sure how you would specify a variable of the appropriate type to store the functor for later use.
Can anyone point me in the right direction here?
template<class MyFunctor> MyMethod(MyFunctor f) {
boost::function<void()> g = f;
g();
}
The type you pass to boost::function is the function type. For example, int(bool, char) is the type of a function returning int and taking a bool and a char. That said, if you want to construct the shared_ptr right away, you don't need to store the functor somewhere (boost::function requires the new operator for that, even though for very small functors, it will use special tricks to only use stack allocation (small buffer optimization)):
template<class MyFunctor> MyMethod(MyFunctor f) {
boost::shared_ptr<T> ptr(new T, f);
}
boost::function is part of tr1 and will be part of the next official C++ Standard. Example:
struct Manager {
template<typename Deleter>
Manager(Deleter d)
:deleter(d) {
}
boost::shared_ptr<Resource> allocate() {
...
return boost::shared_ptr<Resource>(resource, deleter);
}
private:
boost::function<void(Resource *)> deleter;
};
There are two ways, both of which biol down to templating the class.
template <MyFunctor>
class MyClass
{
MyFunctor func;
public:
MyClass(MyFunctor f) :func(f)
{ }
MyMethod()
{
func();
}
}
This would require you to know the type of the functor. To avoid that, we can use a factory:
template<MyFunctor>
MyClass<MyFunctor> MakeFunctorClass(MyFunctor f)
{
return MyClass<MyFunctor>(f);
}
Alternately, since in all likelihood, most of the functor signature will be the same, with only a small part changing, we could use that:
template <MyType>
class MyClass
{
typedef std::binary_function<MyType, MyType, bool> MyFunctor;
MyFunctor func;
public:
MyMethod(MyFunctor f)
{
func = f;
func();
}
}
This makes usage a bit simpler:
bool AreEqual(int, int);
MyClass<int> myc;
myc.MyMethod(AreEqual);
at the expensive of a trickier definition (i.e., I don't guarantee that the binary_function typedef I gave will work)
Not sure if this would help, but be aware that boost::shared_ptr has constructor overrides which allow the user to include a custom de-allocation (and custom allocator, if desired). This might be sufficient for what you need (it's designed with that in mind, if I'm reading your use-case correctly).