Proposal N4282 advocates a new type of non-owning smart pointer called an observer_ptr
. Its working name was exempt_ptr
and it's intended as a replacement for "raw pointers". But I don't understand its purpose, especially with this hypothetical code for what it's designed to achieve:
struct do_nothing
{
template <class T>
void operator ()(T*) { }; // do nothing
};
template <class T>
using non_owning_ptr = unique_ptr<T, do_nothing>;
Even after reading the article, I don't understand the purpose of a smart pointer that doesn't do nothing. What advantage does it have over a non-owning shared_ptr
or raw pointer?
Smart pointers are used to make sure that an object is deleted if it is no longer used (referenced). The unique_ptr<> template holds a pointer to an object and deletes this object when the unique_ptr<> object is deleted.
Smart pointers are designed to be as efficient as possible both in terms of memory and performance. For example, the only data member in unique_ptr is the encapsulated pointer. This means that unique_ptr is exactly the same size as that pointer, either four bytes or eight bytes.
Smart pointers try to prevent memory leaks by making the resource deallocation automatic: when the pointer to an object (or the last in a series of pointers) is destroyed, for example because it goes out of scope, the pointed object is destroyed too.
One of the advantages of smart pointers is, that they ensure due to RAII, that the actual object is deleted. When using a raw pointer, you need to have a delete for every possible exit point, and still an exception will lead to a memory leak. Smart pointers will also free the memory if an exception occurs.
Did you read the "Motivation" section from proposal N4282 that you linked?
It has often proven to be very challenging and time-consuming for a programmer to inspect code in order to discern the use to which any specific bare pointer is put, even if that use has no management role at all. As Loïc A. Joly observed, “it is not easy to disambiguate a T* pointer that is only observing the data.... Even if it would just serve for documentation, having a dedicated type would have some value I think.” Our experience leads us to agree with this assessment.
In other words, it's to make code more self-documenting.
For example, if I see the following function:
void do_something(Foo *foo);
then I don't know if do_something is taking ownership of foo, wants a Foo array of indeterminate length, just needs a nullable reference to it, is using it as a Google C++ Style Guide style output parameter, or is legacy C-style code that just wants a reference.
However, if I see
void do_something(observer_ptr<Foo> foo);
then I know it's observing a Foo instance, and no more.
The C++ Core Guidelines have several additional examples (owner
, not_null
, etc.) of using templates, not to add run-time functionality, but to better document behavior.
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