why not make everything unique_ptr ?

Hi, i just learned about smart pointers and i was wondering:
Is it bad to make all members of a class (or anywhere for that matter) unique_ptr ? as long as the variable are owned by the class and wont be shared? and then just use the the get() function to parse out pointer references to whoever needs it?

I've been reading through some open source projects and alot of them dont do this, so i guess its not a good idea, i was just wondering why ?
Last edited on
i also have another question:

when do you need to use a shared_ptr ?

can't you achieve the same thing just using unique_ptr and move() ?
Last edited on
stav wrote:
Is it bad to make all members of a class (or anywhere for that matter) unique_ptr ?

It would be correct if all members of your class happen to be owning pointers (that is, pointers on which you swear to call free at some point) or some other sort of non-class resource handles on which you swear to call a resource release function. It would be meaningless otherwise.

stav wrote:
when do you need to use a shared_ptr ?

When you can't possibly use anything else. It is the pointer of last resort.
As the Core Guidelines put it in https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Rf-shared_ptr
Core Guidelines wrote:
Prefer a unique_ptr over a shared_ptr if there is never more than one owner at a time. shared_ptr is for shared ownership.
Note that pervasive use of shared_ptr has a cost (atomic operations on the shared_ptr's reference count have a measurable aggregate cost).


In general, I believe the only fully justified use requires two things: 1) ownesrhip is shared between threads and 2) decision on the object lifetime is made at run time

An example of that is the use of shared pointers in many boost.asio (soon to be standard C++ networking) applications, where the handler for socket accept() creates an object where all the state associated with the given network connection is kept, and passes a copy of a shared_ptr holding that object down the callback chains (socket read handlers, socket write handlers, etc), keeping it alive as long as there are any outstanding callbacks. Since it's unknown which thread in boost.asio's thread pool will be the last one, and since multiple callbacks may be simultaneously active on multiple threads, shared_ptr is appropriate and perfect for the job.
Last edited on
1
2
3
4
5
6
class someClass
{
  int a;
  int b;
  string c;
};

is preferable to
1
2
3
4
5
6
class someClass
{
  unique_ptr<int> a;
  unique_ptr<int> b;
  unique_ptr<string> c;
};

Why would you do the second if you didn't have to? It's extra work for no benefit.


and then just use the the get() function to parse out pointer references to whoever needs it?

That's a bad policy to have. It ruins the whole point of having smart pointers.
stav wrote:
and then just use the the get() function to parse out pointer references to whoever needs it?
Repeater wrote:
That's a bad policy to have. It ruins the whole point of having smart pointers.

No. It does not.
If you want to pass a pointer to the object as argument to a function use get(). f(ptr.get());
If you want to pass a reference to the object as argument to a function use *. f(*ptr);
Only pass a smart pointer if you want to transfer ownership.
Last edited on
I disagree. Disagreements happen.

I propose that if I'm using a smart pointer to hold ownership, I shouldn't be passing around unmanaged pointers to the actual thing. Someone will hold and use that pointer beyond the lifetime of the object. Someone will call delete on that pointer because they've misunderstood. Someone will massively misunderstand and will assign it to a different smart pointer. These are all things I've seen done in commercial code; such experiences colour my philosophy. I design my code such that nobody needs to get a raw pointer to something that's being managed by a smart pointer. I accept that sometimes I might have some legacy code that forces me to do bad things; I don't like it and I try not to have to do that.

You have a different philosophy, informed by your own experiences. These things happen.
Last edited on
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Rr-smartptrparam
Core Guidelines wrote:
A function that does not manipulate lifetime should take raw pointers or references instead.
Good for them. I like to avoid the situation of needing to pass around raw pointers to managed objects entirely, when I can. I've seen it go wrong too many times, and that has coloured my philosophy.
Last edited on
Topic archived. No new replies allowed.