17

How to get a reference to an object having shared_ptr<T> to it? (for a simple class T)

jogojapan
  • 68,383
  • 11
  • 101
  • 131
myWallJSON
  • 9,110
  • 22
  • 78
  • 149

2 Answers2

21

operator* already returns a reference:

T& ref = *ptr;

Or, I suppose I could give a more meaningful example:

void doSomething(std::vector<int>& v)
{
    v.push_back(3);
}

auto p = std::make_shared<std::vector<int>>();

//This:
doSomething(*p);

//Is just as valid as this:
vector<int> v;
doSomething(v);

(Note that it is of course invalid to use a reference that references a freed object though. Keeping a reference to an object does not have the same effect as keeping a shared_ptr instance. If the count of the shared_ptr instances falls to 0, the object will be freed regardless of how many references are referencing it.)

Corbin
  • 33,060
  • 6
  • 68
  • 78
  • Even in small examples, it's probably better to use good style: `auto p = std::make_shared>();` – GManNickG Nov 27 '12 at 01:05
  • @GManNickG Yeah, probably true. Will edit in a second. (I'm not actually sure if I would use `auto` here usually. Seems clearer to just use shared_ptr. I've coded a total of about 200 lines of C++11 though, so am not very familiar with what has become good practice/idiomatic for C++11 though.) – Corbin Nov 27 '12 at 01:07
  • Is there a concept of shared refrence? (so that counter would not get to 0 while refs are in scopes)? – myWallJSON Nov 27 '12 at 01:09
  • @Corbin: The guideline here is that you don't want to waste time (or introduce bugs) by specifying the type twice. Now you've only specified it once. (Additionally, this is slightly more performant, for other searchable reasons.) – GManNickG Nov 27 '12 at 01:13
  • @GManNickG Ah, I suppose that makes sense. Will have to retrain my brain to pay attention to the right side of variable declarations for types :). Thanks. – Corbin Nov 27 '12 at 01:14
  • @MyWallJSON Not that I know of (though as I said earlier, I'm not particularly familiar with C++11, nor am I familiar with many libraries like Boost and such). As far as I'm aware, a "shared reference" would require either a garbage collector or some very, very nasty code that would allow an object to be implicitly casted to a reference of the contained type (I don't think that would be feasible though. The usage of it would just be too odd.) – Corbin Nov 27 '12 at 01:18
  • @myWallJSON: What does that mean, "shared reference"? `shared_ptr` already does not let the counter get to 0 while others are in scope. Do you mean `shared_ptr` where the pointer is never null? – GManNickG Nov 27 '12 at 01:46
  • interesting that there is no automatic conversion from `shared_ptr` to T&, I guess that would require an overload for `operator &` which is, of course, an entirely different thing. Also maybe the committees got their fingers burnt with all the automatic converstions they put in in the early days. – pm100 Jan 13 '22 at 00:51
0

Is there a concept of shared refrence?

Yes actually! shared_ptr provides an "aliasing constructor" that can be used exactly for this purpose. It returns a shared_ptr that uses the same reference count as the input shared_ptr but points to a different reference, typically a field or value derived from the backing data.

It is the responsibility of the programmer to make sure that this ptr remains valid as long as this shared_ptr exists, such as in the typical use cases where ptr is a member of the object managed by r or is an alias (e.g., downcast) of r.get()

What is shared_ptr's aliasing constructor for? goes into this in more detail, including an example of how to use it.

dimo414
  • 47,227
  • 18
  • 148
  • 244