1

Say, I've got a library which initializes an object like this:

Type *object;

lib_init(&object); // lib_init takes Type **object as the parameter

So, what if I want to use the library with my code which uses smart pointers? Is this a proper way?

Type *pObject;
lib_init(&pObject);
unique_ptr<Type> object(nullptr);
object.reset(pObject);

Or is there a smart way to do this?

3
  • does the library gives you a way to clean the object up when it's no longer needed? Commented Aug 30, 2015 at 15:36
  • What does the library's documentation say about disposing of the object obtained with lib_init? I would expect there to be a corresponding lib_destroy or something along these lines. It's unlikely that delete object is the right way to dispose of an object allocated by a C language library - but that's what unique_ptr would do unless told otherwise. Commented Aug 30, 2015 at 15:36
  • Yes, there is lib_dispose and I understand that there must be a custom deleter in order to call that function. Actually, the answer to my question is here stackoverflow.com/a/24543176/135749. Exactly the behavior that I was looking for. Thank you, everybody. Commented Aug 30, 2015 at 15:55

2 Answers 2

5

You could wrap the initialization into a function that returns a unique pointer:

std::unique_ptr<Type> init_type()
{
  Type* p;
  lib_init(&p);
  return std::unique_ptr<Type>(p);
}

Then

 std::unique_ptr<Type> object(init_type());

Bear in mind that, unless the pointer is to be de-allocated with delete, you'll need to provide a custom deleter too. For example, assuming the de-allocation function is void lib_dispose(Type*), then

std::unique_ptr<Type, void (*)(Type*)> init_type()
{
  Type* p;
  lib_init(&p);
  return std::unique_ptr<Type, void (*)(Type*)>(p, lib_dispose);
}
Sign up to request clarification or add additional context in comments.

3 Comments

Why not returning directly an unique_ptr ? (and so that handles also case with custom deleter)
@Jarod42 No reason. That makes perfect sense. See edit.
@Jarod42 Thanks, fixed. I don't think make_unique is suitable here, because the legacy API requires initializes a pointer.
2

I don't think you need smart pointer here, you can take the standard library approach for std::string/std::vector etc. - wrap the pointer in RAII mechanism

class CType{
  Type* m_Ptr;

  public:
     CType(){
        lib_init(&m_Ptr);
     }

     ~Ctype(){
        lib_dispose(&m_Ptr);
     }

     //TODO: Copy constructor, move constructor assignment operators..

     operator Type&(){
        return *m_Ptr;
     } 

     operator const Type&() const{
        return *m_Ptr;    
     }

    operator Type*(){
        return m_Ptr;
     } 

     operator const Type*() const{
        return m_Ptr;    
     }

    Type* asPointer(){
         return m_Ptr;
     }
}; 

now use Ctype anywhere you would use regular Type, the polymorphism will kick in when you try to use CType as Type* or Type&..

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.