Reputation: 43
Are there any reasons to still use raw pointers (for managed resources) in C++11/14?
Should resource member variables in a class be held in their own smart pointers for automatic RAII without need for cleanup in destructor?
Is the implementation of smart pointers inlined that there is no overhead in doing so?
Upvotes: 4
Views: 1461
Reputation: 69682
Are there any reasons to still use raw pointers (for managed resources) in C++11/14?
I assume that by "managed resources" you mean "owned resources".
Yes there are reasons:
Should resource member variables in a class be held in their own smart pointers for automatic RAII without need for cleanup in destructor?
Resource member variables, in the best case, should just be members without being obvious pointers, not even smart pointers. Smart pointers are a "bridge" between code manipulating raw pointers and pure RAII style. If you have total control over some code and it's new code, you can totally avoid making any use of smart pointer in your interfaces. Maybe you will need them in your implementations though. Keep in mind that there is no actual rules, only recommendations of what you could result in if you
Is the implementation of smart pointers inlined that there is no overhead in doing so?
Implementation of standard smart pointers is as efficient as they can be so yes most of their code is inlined. However, they are not always free, it depends on what they actually do. For example, in almost all cases, unique_ptr is exactly one raw pointer, with just additional checks around it's places of use. So it's "free". shared_ptr on the other hand have to maintain a counter of how many other shared_ptr refer to the same object. That counter can be changed on several threads doing copies of the shared_ptr, so it have to be atomic. Changing the value of atomic counters is not always free, and you should always assume that there is a higher cost than copying a raw pointer.
So "it depends".
Just:
You will end-up with code that, from the user's perspective, don't seem to manipulate pointers. If you have several layers of code following these rules, the code will be easier to follow and highly maintainable.
On a related note from: When to use references vs. pointers
Avoid pointers until you can't.
Also note that Sean Parents in his recent talks also consider smart pointers to be raw pointers. They can indeed be encapsulated as implementation details of value-semantic types corresponding to the actual concept being manipulated. Additionally using type-erasure techniques in implementations but never exposing them to the user helps extensibility of some library constructs.
Upvotes: 6
Reputation: 10562
RAII is more than just wrapping up new and delete - a smart pointer is a form of RAII but RAII is a lot more than that. A good candidate for RAII is when you have any sort of mirroring functions: new/delete, initialise/teardown, stop/start. So your resource should still have its own RAII class - one that performs its cleanup function in its own destructor.
Upvotes: 0
Reputation: 153909
It depends. If the object is fully owned, constructed and destructed by another object, there is a good case for using an std::unique_ptr
in that other object. If you have an object which owns several such objects, all of which are dynamically allocated in the constructor, then you have to do something; if the semantics of the usual smart pointers isn't appropriate (which is often the case), then you'll have to invent something: in the case of a graph, for example, you might put the root pointer in a base class (initializing it to null), and have the destructor of the base class clean-up the graph, starting at the root.
Of course, unless your class has some sort of dynamic structure like a graph, you might ask yourself why it is using dynamic allocation to begin with. There are special cases (where, for example, the owned object is polymorphic, and its actual type depends on arguments to the constructor), but in my experience, they aren't that common. In practice, there just aren't that many cases where a smart pointer can be used in an object, much less should be used.
Upvotes: 0