我有一个结构 A,它有一个成员另一个结构 C。所以 A 以 c1Ptr_ 作为成员。 我使用 2 个结构 S 和 N.N 作为成员 A,a_ 和 S 作为成员 C,c_。 在我实例化 A 并使用创建的 A 对象为 S 创建一个 c 对象并将创建的 A 对象传递给 N 之后,我希望在 N 中也有 A->c1Ptr_.
谢谢。
#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 Nn";
}
else
{
std::cout<<"c1Ptr is NOT set for Nn"; // why c1Ptr is not set for n.a_ ?
}
return 0;
}
shared_ptr
不共享指针,它共享指针的所有权。
这意味着您可以更改单个shared_ptr
以指向其他内容,独立于其他shared_ptr
,但是一旦没有指向某些内容的shared_ptr
,该内容就会被删除。可以将其视为向指针添加计数器。创建、删除或将shared_ptr
重新分配给 nullptr 以外的内容时,将递增或递减计数器。如果计数器达到 0(通常在删除时),那么它也会删除指针。
在您的情况下,您正在从 a 复制一个空点。因此,您有两个shared_ptr
都存储 nullptr。然后你改变其中一个指向一个新事物(12)。这不会更改内存中的其他任何内容,或者特别是其他shared_ptr
的值。
您可以尝试通过绘制对象a
、s
和n
及其内容以及它们的内容来自己解决这个问题:
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]
在此初始指令块之后:
a
和s
的共享指针成员c1Ptr_
值为 nullptr。n
具有指向对象a
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 Nnn"; } else { std::cout << "c1Ptr is NOT set for Nnn"; // (1) }
这里:
- 你只是修改
s.c1Ptr_
,但这不会影响a
,最终n
。 s.c1Ptr_
最初设置为指向与a.c1Ptr_
相同的C1
对象(实际上是nullptr);现在你只是让它指向其他东西。
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 Nnn"; // (2) } else { std::cout << "c1Ptr is NOT set for Nnn"; }
如果你换了a->c1Ptr_
会发生什么?由于n->a_
指向a
并且我们正在修改a
,因此也设置了n->a_->c1Ptr_
。
[演示]