Shared_ptr实例未按预期为对象设置



我有一个结构 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的值。

您可以尝试通过绘制对象asn及其内容以及它们的内容来自己解决这个问题:

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]

在此初始指令块之后:

  • as的共享指针成员c1Ptr_值为 nullptr。
  • n具有指向对象aa_共享指针成员。
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_

[演示]

相关内容

  • 没有找到相关文章

最新更新