Reputation: 2640
Through the use of smart pointers or not. I'd like to make it explicit to the user of a library that all pointers they pass into the library should now be owned by the library (ie. not released by the user).
Many open source libraries just state it in their documentation that the library owns everything or does not. They discuss expected life time of pointers being passed in. Surely there is a more strict way to convey this information to the user.
An example would be great.
Thanks!
Upvotes: 3
Views: 133
Reputation: 14591
If you really want that then you should provide methods in the library to also create these objects, instead of having users allocate them. It doesn't make sense that the library releases the object it has not created, as it can not guarantee that they both use same allocation facility.
There is an option that the library creates these objects, wrapped in a custom smart pointer which hides the pointer and doesn't allow external client to release the wrapped objects, but it is always possible to circumvent the guards. In my experience, trying to be too smart always backfires: things get more complicated, but the developer using the library can always outsmart it.
IMO, the safest approach is a simple lifecycle management API (e.g. CreateObject, DestroyObject) and clear and concise documentation. Then the user is free to choose how to handle the lifetime (e.g. shared_ptr
/unique_ptr
with DestroyObject
as custom deleter, or something completely different).
Upvotes: 2
Reputation: 532
One way to do it would be to overload the new/delete operators, and use those functions to filter access. For example, new might create the object, then store the address into some private static data structure. Delete could be designed so that it blocks any attempt to use the delete object
idiom, unless certain conditions are met.
Upvotes: 0
Reputation: 157374
If you write your library functions, methods and constructors to take std::unique_ptr<T>
by value, then there will be no way for the user to release the pointer themselves as their unique_ptr
instances will be cleared on move-copy of the arguments.
class C;
void library_function(std::unique_ptr<C> by_value);
void user_code() {
std::unique_ptr<C> user_c{std::make_unique<C>("param", 5)};
library_function(user_c);
assert(user_c.get() == nullptr);
}
If the user should be able to continue to observe the object, then you could accept shared_ptr
on the interface, or you could provide observer methods that return a raw (non-owning) pointer or (better) a reference.
Upvotes: 0
Reputation: 63200
Use an owning smart pointer in all your classes, that will take ownership (ie will destroy the object once done with it) and any pointers passed from the users will be taken over by this owning smart pointer.
A good example is std::unique_ptr
, once things are done, will destroy it's object.
If you need custom destruction, you can pass it a custom deleter.
Even better is of course to have both creation (ie through make_unique
) in your classes too, as you will then have RAII, which will avoid all leaks.
Upvotes: 2