指向共享\u ptr的成员变量的指针 在C++中,通过共享对象访问成员变量的安全方法是什么?

指向共享\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; }

在下面的代码中,我创建了一个共享变量,然后创建了一个指向其成员变量的指针。但是,use_计数保持不变,当我重置共享变量时,原始变量被重置,但不是指向成员的指针

换句话说,我可以通过使用b引入一些bug。它指向的对象不应该再存在了

#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;