You're passing a copy of shared_ptr<A>
to the instance of B
. When you assign a new object to a
by calling reset
, the copy stored in b
has no idea this has happened. This is why it never sees the update.
Calling shared_ptr::reset
makes that instance of the shared_ptr
relinquish ownership of the managed object, which means decrementing the use_count
and destroying the object if that instance happens to be the sole owner. If it's not the sole owner, then the other shared_ptr
s managing that object become responsible for managing its lifetime. In either case, the instance that you invoked reset
is now free to take ownership of another object that you may have passed as an argument. In your case this is all a bit simpler since there is no object being managed initially, but the same logic applies. The copy stored within b
is in no way linked to a
after the call to reset
.
Say your class A
implements two member functions, activate()
and is_active()
, with obvious functionality. Also assume that constructing an instance of A
leaves it in a deactivated state until you call activate()
. Then you could solve this problem as follows:
auto a = make_shared<A>();
B b(a);
a->activate();
// within the thread
while (!_this->_a->is_active()) {}
Even so, you'd need to use some synchronization primitive to a prevent data race. For instance, if activate()
sets a boolean data member, the type of that member should be std::atomic<bool>
or std::atomic_flag
, instead of a plain bool
. The same applies to any other data members that maybe read from and written to from different threads.