Deleting a Template Type - c++

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.

Related

Create a smart-pointer-to-base-class from a reference

I have a container which store a vector of smart-pointer-to-base-class, and I'd like to populate it via a method without requiring my users to also create that smart pointer:
class Base {
// ...
};
class Derived: public Base {
// ...
};
class Collection {
private:
vector<unique_ptr<Base>> pointers;
public:
void add(Base&& value) // #1
{
pointers.push_back(????);
}
void add<typename T>(T&& value) // #2
{
pointers.push_back(????);
}
};
int main() {
Collection collection;
collection.add(Derived("Data")); // #3
}
What's the correct way to do this, if at all? It's clear that I could use make_unique and emplacement, except that I'm concerned that the derived content won't be moved correctly.
It's possible I've spent too much time in Rust land, where moves of this kind are pretty commonplace, so let me know if I'm way off base here. Ideally, the interface looks like my #3 point up there, where the function can be called with a literal of the derived type without any extra boilerplate related to allocation or anything. I'd be find if the solution ends up being to make Collection::add generic.
You should probably stick to the template, yes. You then get
class Collection {
std::vector<std::unique_ptr<Base>> pointers;
public:
template<typename T>
void add(T &&value) {
pointers.emplace_back(std::make_unique<std::remove_reference_t<T>>(std::forward<T>(value)));
}
};
int main() {
Collection c;
Derived d;
c.add(d); // works with lvalues (copying)
c.add(std::move(d)); // or rvalues (moving)
Base b;
c.add(b);
c.add(std::move(b));
}
However, it might be more useful to provide an "emplace", which constructs an object out of arbitrary arguments (as provided by all the standard containers)
class Collection {
std::vector<std::unique_ptr<Base>> pointers;
public:
template<typename T, typename... Ts>
void emplace(Ts&&... args) {
pointers.emplace_back(std::make_unique<T>(std::forward<Ts>(args)...));
}
template<typename T> // still useful for conciseness (don't have to specify T)
void add(T &&value) {
this->emplace<std::remove_reference_t<T>>(std::forward<T>(value));
}
};
So you can further do
int main() {
Collection c;
Derived d;
c.add(d); // works with lvalues
c.add(std::move(d)); // or rvalues
c.emplace<Derived>(); // or can give arguments directly (assuming a default constructor, in this case)
Base b;
c.add(b);
c.add(std::move(b));
c.emplace<Base>();
}
A complete example on Godbolt.

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.

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());

Using arbitrary owning pointer without templating

I would like to pass (shared) ownership of an object to a function foo::bar.
The thing is I do not care, whether the ownership is exclusive or shared.
I see class foo as an interface where I do not want to care about the ownership details.
All I care about is that I can secure the lifetime of the passed smart pointer beyond the return of foo::bar.
Now I could write
class foo {
void bar( std::shared_ptr<blub> );
void bar( std::unique_ptr<blub> );
};
but this is unelegant in times where we have accumulated several smart pointer variants.
And writing an overload for every variant is quite cumbersome, especially if I want to use this scheme multiple times in my code.
Now I also do not want foo to be templated, for the obvious template complexities.
The simplest I can come up with would be a smart pointer wrapper
template <typename T>
class owning_ptr {
// Sorts out the largest type so we can allocate enough space
typedef largest<std::shared_ptr<T>, std::unique_ptr<T>, myptr<T>>::type big_type;
typedef std::aligned_storage <sizeof(big_type), std::alignment_of<big_type>::value>::type buffer_type;
buffer_type _internal;
int _type;
};
which is a bit inefficient. Is there a better way to construct the wrapper?
In the end I would really like to have the signature:
class foo {
void bar( owning_ptr<blub> );
};
Note: There's an interesting EDIT at the bottom
If you don't want to parameterize or overload on the owning pointer type, you're probably best off taking a shared_ptr<> and forcing a conversion for unique_ptr<>. Any non-template solution I can think of would have at least the same amount of overhead as a shared_ptr, most requiring a polymorphic call, a free-store allocation, or both.
You might be able to automate the conversion from shared_ptr by taking some type of proxy converter, which should allow you to take either a unique_ptr R-value or a shared_ptr without a cast or explicit conversion (other than move()) and extract a usable shared_ptr to store in your instance. Here's an example:
#include <iostream>
#include <memory>
#include <utility>
using namespace std;
// Take an instance of gimme_owned_ptr<T> to save off a shared_ptr<T>
// from either a shared_ptr or unique_ptr.
template<typename T>
struct gimme_owned_ptr {
// Make the two constructors templates so we can accept
// any convertible owning pointer:
template<typename S>
gimme_owned_ptr( unique_ptr<S> p )
: p_( shared_ptr<S>( move(p) ) )
{ }
template<typename S>
gimme_owned_ptr( shared_ptr<S> p )
: p_( p )
{ }
shared_ptr<T> get() const {
return p_;
}
private:
shared_ptr<T> p_;
};
struct Foo {
void operator()() const { v_call(); }
virtual ~Foo() { }
private:
virtual void v_call() const = 0;
};
struct Bar {
Bar( gimme_owned_ptr<Foo const> const &gop )
: foo_( gop.get() )
{ }
void operator()() const { (*foo_)(); }
private:
shared_ptr<Foo const> foo_;
};
struct Baz : Foo {
private:
virtual void v_call() const { cout << "Baz()()\n"; }
};
int main() {
unique_ptr<Baz> upf( new Baz() );
shared_ptr<Baz> spf( new Baz() );
Bar upb( move( upf ) );
Bar spb( spf );
upb();
spb();
}
Yes, this solution does use templates, but only for the gimme_owned_ptr utility class template, and only for re-use and conversion. Your own class (Bar in this case) wouldn't need to be a template, nor would you need to re-implement gimme_owned_ptr to use it with another type.
======== EDIT ========
I just checked, and the built-in conversion from unique_ptr to shared_ptr essentially does everything the gimme_owned_ptr class I wrote above. If the class takes a type of shared_ptr<T>, passing a move(unique_ptr<S>) will result in a workable conversion. So, all you really need is to take a shared_ptr and the only thing the user should have to do is call move() on unique_ptrs (which they should be doing anyway). The only reason to use something like gimme_owned_ptr would be to accept a different mixture of pointers or accept them in a different way. (For example, you could make the move() unnecessary by taking a unique_ptr<S>& and calling move() internally, but this is probably a bad idea as it will silently seize ownership.)

Using an abstract deleter with std::unique_ptr

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.