指向 shared_ptr 成员变量的指针
Pointer to member variable of shared_ptr
在 C++ 中通过共享对象访问成员变量的安全方法是什么?
在下面的代码中,我创建了一个共享变量,然后创建了一个指向它的成员变量的指针。但是,use_count 保持不变,当我重置共享变量时,原始变量被重置但不是指向成员的指针。
换句话说,我可以通过使用 b 引入一些错误。它指向的对象不应该再存在了。
#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;
}
auto b = a->y;
这将复制 y
的值,因此它不是指向y
的指针,它只是一个副本。
What is a safe way to accessing member variables through a shared object in C++?
你已经在做了。您显示的代码是安全的。
In the code below, I make a shared variable and then a pointer to a member variable of it.
不,你不知道。 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); // or just: auto b = ...
...
cout << "b value: " << *b << endl;
However, the use_count remains unchanged
正确,因为您没有将 a
分配给 shared_ptr<A>
的另一个实例。这就是 use_count
所代表的 - 在内存中共享同一对象的 shared_ptr
个对象的数量。
when I reset the shared variable the original variable is reset but not the pointer to member.
当然,因为 b
独立于 a
并且不是指向任何与 a
相关的指针。
In other words, I could introduce some bugs by using b.
没有,因为b
没有链接到a
,所以重置a
对b
没有影响。
现在,如果您确实设法完成了您的要求(使 b
成为指向 y
的指针),您有责任确保 A
对象y
的访问在内存中保持有效,直到您使用 b
完成,否则取消引用 b
将是 未定义的行为 。 STL 不会让你免于在背后做一些愚蠢的事情,比如在对象被销毁后通过原始指针访问 A
对象的成员。
这个故事的寓意是不要分发对可能在引用之前死亡的对象的引用。设计时要考虑到每个物体的使用寿命。一种解决方案可能是复制 std::shared_ptr
以确保引用始终指向对象,另一种解决方案可能是在不需要对象仍然有效但需要时传递 std::weak_ptr
知道所以你不要尝试使用它。仅当您知道对象将比它们长寿时才传递指针和引用。
auto a = make_shared<A>(1);
auto b = std::shared_ptr<int>(a, &a->y);
b 是指向 y 的共享指针,可以满足您的需求。
这就是共享指针的 "aliasing constructor"。它正是为此目的而设计的;将共享指针指向更大共享指针的一部分。
你可以用它来做很多疯狂和奇特的事情。使用它时要小心,因为您可能会遇到奇怪的状态,例如空非空共享指针和非空空共享指针。但是如果你像上面那样使用它"normally",它就可以正常工作。
你做了什么
auto a = make_shared<A>(1);
auto b = a->y;
简单地将y
复制到b
,不涉及指针。
在 C++ 中通过共享对象访问成员变量的安全方法是什么?
在下面的代码中,我创建了一个共享变量,然后创建了一个指向它的成员变量的指针。但是,use_count 保持不变,当我重置共享变量时,原始变量被重置但不是指向成员的指针。
换句话说,我可以通过使用 b 引入一些错误。它指向的对象不应该再存在了。
#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;
}
auto b = a->y;
这将复制 y
的值,因此它不是指向y
的指针,它只是一个副本。
What is a safe way to accessing member variables through a shared object in C++?
你已经在做了。您显示的代码是安全的。
In the code below, I make a shared variable and then a pointer to a member variable of it.
不,你不知道。 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); // or just: auto b = ...
...
cout << "b value: " << *b << endl;
However, the use_count remains unchanged
正确,因为您没有将 a
分配给 shared_ptr<A>
的另一个实例。这就是 use_count
所代表的 - 在内存中共享同一对象的 shared_ptr
个对象的数量。
when I reset the shared variable the original variable is reset but not the pointer to member.
当然,因为 b
独立于 a
并且不是指向任何与 a
相关的指针。
In other words, I could introduce some bugs by using b.
没有,因为b
没有链接到a
,所以重置a
对b
没有影响。
现在,如果您确实设法完成了您的要求(使 b
成为指向 y
的指针),您有责任确保 A
对象y
的访问在内存中保持有效,直到您使用 b
完成,否则取消引用 b
将是 未定义的行为 。 STL 不会让你免于在背后做一些愚蠢的事情,比如在对象被销毁后通过原始指针访问 A
对象的成员。
这个故事的寓意是不要分发对可能在引用之前死亡的对象的引用。设计时要考虑到每个物体的使用寿命。一种解决方案可能是复制 std::shared_ptr
以确保引用始终指向对象,另一种解决方案可能是在不需要对象仍然有效但需要时传递 std::weak_ptr
知道所以你不要尝试使用它。仅当您知道对象将比它们长寿时才传递指针和引用。
auto a = make_shared<A>(1);
auto b = std::shared_ptr<int>(a, &a->y);
b 是指向 y 的共享指针,可以满足您的需求。
这就是共享指针的 "aliasing constructor"。它正是为此目的而设计的;将共享指针指向更大共享指针的一部分。
你可以用它来做很多疯狂和奇特的事情。使用它时要小心,因为您可能会遇到奇怪的状态,例如空非空共享指针和非空空共享指针。但是如果你像上面那样使用它"normally",它就可以正常工作。
你做了什么
auto a = make_shared<A>(1);
auto b = a->y;
简单地将y
复制到b
,不涉及指针。