Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A non-shared smart pointer with incomplete types

Is there a standard pointer class (or Boost) which is a non-shared pointer that works with incomplete types? I've gone over the C++11 standard and the boost library and can't find one, though it seems like a very useful type.

For example, I'd like to be able to make opaque types using a smart pointer.

  class A;
  wrap_ptr<A> some_func();
  void other_func( A const & );

A is an opaque type which can be used for a variety of functions. The user of the above interface has only an incomplete definition of A but should be able to delete/reset the pointer. I know the above can be done with a shared_ptr but that has an overhead I don't want in this particular code. unique_ptr has the right ownership semantics, but can't work with an incomplete type. In theory a wrapper should need only the overhead of having a pointer to a deleter.

Is there such a type in C++11 or the boost libraries?

NOTE: I understand I can easily build this type, but I'd prefer a standard type if possible. It seems like it should be a fundamental smart pointer type.


UPDATE: unique_ptr does not appear to be a good option. First off the syntax overhead would be offsetting. Secondly I'm not convinced it can be safely used with a custom deleter. I'll check to see how it might work.

like image 986
edA-qa mort-ora-y Avatar asked Jan 30 '12 09:01

edA-qa mort-ora-y


People also ask

How many types of smart pointers are there in C++?

There are three common types of Smart Pointers in C++ they are Unique_ptr, Shared_ptr, and Weak_ptr.

Is shared pointer a smart pointer?

Shared pointers are smart pointers that keep a count of how many instances of the pointer exist, and only clean up the memory when the count reaches zero. In general, only use shared pointers (but be sure to use the correct kind--there is a different one for arrays).

What is the difference between the two smart pointers shared_ptr and unique_ptr?

In short: Use unique_ptr when you want a single pointer to an object that will be reclaimed when that single pointer is destroyed. Use shared_ptr when you want multiple pointers to the same resource.


3 Answers

To be clear about unique_ptr : it does work with incomplete type, but if you use it in a header of a class like that :

#include <memory>

class A;

class B
{

std::unique_ptr<A> m_a;

};

It will not link because of the missing deleter implementation. There is an easy fix to this : just define de destructor of the host class in a cpp, even if it's empty or should be the default one!

// B.hpp
#include <memory>

class A;

class B
{
public:

    B();
    ~B();

private:

std::unique_ptr<A> m_a;

};

// B.cpp

B::B(){} // or =default; (if you have a compiler providing it)
B::~B(){} // or =default; (if you have a compiler providing it)

Also, read answers to my question there : Is std::unique_ptr<T> required to know the full definition of T?

And maybe take a look at how pimpl idiom (implying uncomplete type in a unique_ptr) is recommended to be implmented by Herb Sutter: http://herbsutter.com/gotw/_100/

like image 191
Klaim Avatar answered Nov 11 '22 09:11

Klaim


Actually, unique_ptr can work with incomplete types, as long as you specify a custom deleter.

However, contrary to shared_ptr, this actually influence its type, as the custom deleter is precised statically (as the second template parameter).

like image 26
Matthieu M. Avatar answered Nov 11 '22 07:11

Matthieu M.


std::unique_ptr can handle this case, but not with the default deleter. You need to write a deleter that can handle an incomplete type, and then use std::unique_ptr<A,MyDeleter>.

like image 2
Anthony Williams Avatar answered Nov 11 '22 09:11

Anthony Williams