指向共享\u ptr的成员变量的指针 在C++中,通过共享对象访问成员变量的安全方法是什么?
在下面的代码中,我创建了一个共享变量,然后创建了一个指向其成员变量的指针。但是,use_计数保持不变,当我重置共享变量时,原始变量被重置,但不是指向成员的指针 换句话说,我可以通过使用b引入一些bug。它指向的对象不应该再存在了指向共享\u ptr的成员变量的指针 在C++中,通过共享对象访问成员变量的安全方法是什么?,c++,c++11,shared-ptr,pointer-to-member,C++,C++11,Shared Ptr,Pointer To Member,在下面的代码中,我创建了一个共享变量,然后创建了一个指向其成员变量的指针。但是,use_计数保持不变,当我重置共享变量时,原始变量被重置,但不是指向成员的指针 换句话说,我可以通过使用b引入一些bug。它指向的对象不应该再存在了 #include <iostream> #include <memory> using namespace std; struct A { int y; A(int x) { y = x; }
#include <iostream>
#include <memory>
using namespace std;
struct A
{
int y;
A(int x)
{
y = x;
}
};
int main()
{
auto a = make_shared<A>(1);
cout << "a count: " << a.use_count() << endl; //prints a count: 1
auto b = a->y;
cout << "a count: " << a.use_count() << endl; //still prints a count: 1
a.reset();
cout << "a value: " << a << endl; //prints a value: 0
cout << "b value: " << b << endl; //prints b value: 1
return 0;
}
#包括
#包括
使用名称空间std;
结构A
{
int-y;
A(整数x)
{
y=x;
}
};
int main()
{
自动a=使共享(1);
库特
这将复制y
的值,因此它不是指向y
的指针,它只是一个副本
<>在C++中,通过共享对象访问成员变量的安全方法是什么?
你已经在做了。你显示的代码是安全的
在下面的代码中,我创建了一个共享变量,然后创建了一个指向其成员变量的指针
不,您没有。A::y
是一个int
。在auto b=A->y;
语句中,auto
推断为int
,而不是int&
或int*
。因此,您正在创建一个新的int
,其值是y
的副本。没有指向y
的指针
如果您想要这样的东西,您需要使用以下其中一种:
auto &b = a->y;
...
cout << "b value: " << b << endl;
auto&b=a->y;
...
cout这个故事的寓意是,不要将引用分发给可能在引用之前死亡的对象。设计时要考虑每个对象的寿命。一个解决方案可能是复制std::shared\u ptr
以确保引用始终指向对象。另一个解决方案可能是在不需要时传递std::weak\u ptr
不需要对象仍然有效,但你需要知道,这样你就不会尝试使用它。只有当你知道对象的寿命超过它们时,才会发出指针和引用。auto a=make\u shared(1);
auto a = make_shared<A>(1);
auto b = std::shared_ptr<int>(a, &a->y);
自动b=std::shared_ptr(a,&a->y);
b是一个指向y的共享指针,它执行您想要的操作
这被称为共享ptr的“别名构造函数”。它正是为了这个目的而设计的;它将一个共享指针插入一个更大的共享ptr的一部分
你可以在上面用它来做很多疯狂和新奇的事情。使用它时要小心,因为你可能会得到一些奇怪的状态,比如空的非空共享PTR和非空的空共享PTR。但是如果你像上面那样“正常”使用它,它会工作得很好
你做了什么
auto a = make_shared<A>(1);
auto b = a->y;
auto a=make_shared(1);
自动b=a->y;
只需将y
复制到b
,不涉及任何指针。也许您可以结合使用共享ptr和指向成员的指针,例如a::*y,这取决于您的用例如果您试图防止从不同线程并发访问同一成员,您可以使用std::mutex你可能想使用shared_ptr的别名构造函数:std::shared_ptr(a,&a->y)
是的,你是对的。我想我真正想要的是auto b=&(a->y)
然后在cout语句中*b
。“此外,调用此函数的副作用与在其值更改之前调用shared_ptr的析构函数的副作用相同(如果此shared_ptr是唯一的,则包括删除托管对象)”,因此您将打印销毁的对象,这是UB。这是一个很好的答案。是的,我的意思是auto b=&(a->y)
谢谢。这将返回使用2的计数()。
auto a = make_shared<A>(1);
auto b = std::shared_ptr<int>(a, &a->y);
auto a = make_shared<A>(1);
auto b = a->y;