Reputation: 3
I have a struct A which has a member another struct C. So A with c1Ptr_ as member.
I use 2 structs S and N. N has as member A, a_ and S has as member C, c_.
After I instantiated A and create for S a c object using the created A object and I pass the created A object to N I would expect to have the A->c1Ptr_ in N as well.
Thank you.
#include <iostream>
#include <memory>
using namespace std;
struct C1
{
C1(int x):x_(x)
{
std::cout<<"-C1: x_: " << x_ << std::endl;
}
int x_;
~C1()
{
std::cout<<"-DC1: x_: " << x_ << std::endl;
}
};
using C1ptr = std::shared_ptr<C1>;
struct A
{
C1ptr c1Ptr;
};
struct S
{
S(C1ptr& c1Ptr):c1Ptr_(c1Ptr)
{
}
C1ptr c1Ptr_;
};
struct N
{
N(std::shared_ptr<A> a):a_(a)
{
}
std::shared_ptr<A> a_;
};
int main()
{
std::shared_ptr<A> a = std::make_shared<A>();
S s(a->c1Ptr);
N n(a);
s.c1Ptr_ = std::make_shared<C1>(12);
if (n.a_->c1Ptr)
{
std::cout<<"c1Ptr is set for N\n";
}
else
{
std::cout<<"c1Ptr is NOT set for N\n"; // why c1Ptr is not set for n.a_ ?
}
return 0;
}
Upvotes: 0
Views: 156
Reputation: 8074
You can try to work this out on your own by drawing the objects a
, s
, and n
and their contents, and what their contents point to:
auto a = std::make_shared<A>(); // a(c1Ptr_ = null) S s(a->c1Ptr_); // a(c1Ptr_ = null), s(c1Ptr_ = null) N n(a); // a(c1Ptr_ = null), s(c1Ptr_ = null), n(a_ = a) // [n.a_ points to a]
After this initial block of instructions:
a
and s
have their shared pointer members c1Ptr_
with a value of nullptr.n
has its shared pointer member a_
pointing to the object a
.s.c1Ptr_ = std::make_shared<C1>(12); // (1) a(c1Ptr_ = null), s(c1Ptr_->x_ = 12 ), n(a_ = a) // [and you modify s] if (n.a_->c1Ptr_) { std::cout << "c1Ptr is set for N\n\n"; } else { std::cout << "c1Ptr is NOT set for N\n\n"; // (1) }
Here:
s.c1Ptr_
, but that doesn't affect a
, and ultimately, n
.s.c1Ptr_
was originally set to point to the same C1
object as a.c1Ptr_
(actually, nullptr); now you're just making it point to something else.a->c1Ptr_ = std::make_shared<C1>(15); // (2) a(c1Ptr_->x_ = 15 ), s(c1Ptr_->x_ = 12 ), n(a_ = a) // [and you modify a] if (n.a_->c1Ptr_) { std::cout << "c1Ptr is set for N\n\n"; // (2) } else { std::cout << "c1Ptr is NOT set for N\n\n"; }
What would have happened if you had changed a->c1Ptr_
instead? Since n->a_
points to a
and we are modifying a
, n->a_->c1Ptr_
is also set.
Upvotes: 0
Reputation: 11968
shared_ptr
doesn't share a pointer, it shares ownership of a pointer.
This means that you can change individual shared_ptr
to point to other things, indepnendent of other shared_ptr
's, but as soon as there's no shared_ptr
pointing at something, that something get's deleted. Think of it as adding a counter to the pointer. When you create, delete or reassign a shared_ptr
to something other than nullptr, you will increment or decrement the counter. If the counter reaches 0 (usually on a delete) then it also deletes the pointer.
In your case you are copying a nullptr from a. So you have two shared_ptr
both storing nullptr. Then you change one of them to point to a new thing (12). This won't change anything else in memory, or specifically the value of other shared_ptr
s.
Upvotes: 1