I'm using an old open-source library, with the following (simplified) API of interest:
// some class that holds a raw pointer to memory on the heap
// DOES NOT delete it in its destructor
// DOES NOT do a "deep" copy when copied/assigned (i.e., after copying both objects
// will point to the same address)
class Point;
// function used to construct a point and allocate its data on the heap
Point AllocPoint();
// function used to release the memory of the point's data
void DeallocPoint(Point& p);
// Receives a pointer/c-array of Points, along with the number of points
// Doesn't own the memory
void Foo(Point* points, int npts);
What's the best (safest/most readable/most elegant) way of using this API in C++11. I can't simply use vector<unique_ptr<Point, PointDeleter>>
(where PointDeleter
is a simple custom deleter I can implement), because then I will not be able to use the function Foo
(which expects Point*
and not unique_ptr<Point>*
).
Thanks
Introduction of Smart PointersC++11 comes up with its own mechanism that's Smart Pointer. When the object is destroyed it frees the memory as well. So, we don't need to delete it as Smart Pointer does will handle it.
Smart pointers are class objects that behave like raw pointers but manage objects that are new and when or whether to delete them— smart pointers automatically delete the managed object at the appropriate time.
Smart Pointers in C++Smart pointer in C++, can be implemented as template class, which is overloaded with * and -> operator. auto_ptr, shared_ptr, unique_ptr and weak_ptr are the forms of smart pointer can be implemented by C++ libraries.
A raw pointer is a pointer whose lifetime isn't controlled by an encapsulating object, such as a smart pointer. A raw pointer can be assigned the address of another non-pointer variable, or it can be assigned a value of nullptr . A pointer that hasn't been assigned a value contains random data.
If you really want to make it look nice, you're probably going to have to write a set of really comprehensive wrappers which completely hide the library's API - effectively, wrap the entire library with one that behaves in a modern C++ way on the outside and hides all the mess inside.
Not a pleasant task, but if you can get the behaviour of that library right then it should make your life a lot easier in the long term. Might not be worth it if you're not going to use this external library very extensively though.
I would wrap this non-RAII C-like API in RAII building blocks, and then use them in C++11 code.
For example: you can define a RaiiPoint
class that wraps the (non-RAII) Point
class, and in its constructor calls AllocPoint()
, in the destructor DeallocPoint()
. Then you can define proper copy constructor and copy operator=
, or just implement move semantics (with move constructor and move operator=
), or make the wrapper class both copyable and movable, basing on your requirements.
Then you can simply use a std::vector<RaiiPoint>
with your RAII-based wrapper class.
(This is a general approach that you can use when you want to use C libraries in modern C++ code: you can wrap the "raw" C library handles and objects in safe RAII boundaries, and use these robust safe wrapper classes in your modern C++ code.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With