从共享指针的取消引用值中获取共享指针
Get a shared pointer from a dereferenced value of a shared pointer
想象一下有一个共享指针的向量
typedef vector< shared_ptr< classA > > PointerVector;
还有一个 B 类,它的成员也是共享指针的向量,以及一个在此向量中推回已经取消引用的共享指针的方法。
ClassB
{
public:
void add(classA &ref);
private:
PointerVector vector;
}
假设 main 使用取消引用的 shared_ptr<类 A=">实例为 add 函数提供:类>
在主要:
shared_ptr< classA > sharedptr ( new classA );
ClassA &ref = *sharedptr;
ClassB B;
B.add(ref);
有没有办法实现 add 函数来接受取消引用的共享指针并将其转换为初始共享指针? 然后将其推回矩阵中?
这就是我正在尝试做的:
void ClassB::add(classA &ref) {
shared_ptr< classA > ptr = &ref;
vector.push_back( ptr );
}
注1:当类A添加到向量时,我希望共享指针计数增加1。我不需要创建另一个共享指针,我想"查找"对象以前拥有的共享指针。
注2:我无法使用make_shared,因为我目前在TR1中
通常,您不能只是"找到">指向对象的指针,因为如果指向或不指向特定对象,则无法跟踪。您应该自己设计这样的机制,或者使用标准库提供的机制:enable_shared_from_this
。
第 1 步:从std::enable_shared_from_this
派生类,并提供一个成员函数来获取指针:
#include <memory>
struct ClassA: std::enable_shared_from_this<ClassA>
{
std::shared_ptr<ClassA> get_pointer()
{
return shared_from_this();
}
//...
};
第 2 步:确保要获取指针的所有对象都由shared_ptr
管理:
std::shared_ptr<ClassA> original_ptr(new ClassA);
第 3 步:每当你想要获取指向对象的共享指针时,调用步骤 1 中定义的函数:
void ClassB::add(classA& ref) {
shared_ptr<classA> ptr = ref.get_pointer();
vector.push_back( ptr );
}
有一种方法可以做到这一点,但需要这样做可能意味着存在设计缺陷。
为什么它不起作用
shared_ptr
需要参考计数器才能工作。此计数器保存在创建第一个shared_ptr
时创建的控制块中。复制shared_ptr
时,复制不仅会复制指向托管对象的指针,还会复制指向控制块的指针。这允许它访问引用计数器并在销毁对象时销毁块。
采用ClassA &
的函数无法访问控制块。尝试创建新shared_ptr
将创建一个引用计数为 1 的新控制块。当任一引用计数器达到 0 时,对象将被销毁。因此,它将被销毁两次,这是未定义的行为。
它是如何工作的
正如评论中已经提到的,std::enable_shared_from_this
解决了您的问题。你必须让你的类从中派生出来。
ClassA : std::enable_shared_from_this<ClassA> {...}
然后,可以调用ClassA.shared_from_this()
来获取shared_ptr
,该是同一对象的现有shared_ptr
的副本。
为什么我不建议使用它
你必须非常小心enable_shared_from_this
. cppreference.com 状态
只允许在以前共享的对象上调用shared_from_this,即在由 std::shared_ptr 管理的对象上。否则,行为是未定义的(直到 C++17)std::bad_weak_ptr 被抛出(由默认构造weak_this中的shared_ptr构造函数引发)(自 C++17 以来)。
因此,在尝试使用shared_from_this
方法从对象创建新shared_ptr
之前,必须确保对象已共享。
此外,您的函数签名接受ClassA&
.可以使用堆栈上的参数调用它;从堆栈对象创建shared_ptr
是危险的。如果您的函数需要共享所有权,它应该只接受shared_ptr<ClassA>
以便传达其意图。这使得它自我记录,并且在不牺牲任何东西的情况下更难处理不当。
- 如何从具有移动语义的类对象中生成共享指针
- 使用共享指针的函数调用,其对象应为 const
- 共享指针和具有自定义删除程序的唯一指针之间的语法差异背后的任何原因
- 如何访问由共享指针保存的类方法?
- 从矢量或地图中删除共享指针
- 使用共享指针时,从共享指针本身释放内存的机制是什么
- 使用共享指针实现复制 c'tor?
- 共享指针继承,而不先显式强制转换
- 如何检查类中共享指针的有效性?
- std::排序在共享指针的向量上
- 将相同共享指针的副本存储在不同的向量中是否是一种好的做法?
- 嵌套类、继承和C++中的共享指针
- 制作一对共享指针并推送一个向量
- 如何将共享指针用作函数参数
- 是否可以/希望创建不可复制的共享指针模拟(以启用weak_ptr跟踪/借用类型语义)?
- 尝试通过共享指针使用变量时读取访问冲突
- 如何将元素插入到标准::地图的共享指针中?
- 共享指针生存期
- 初始化可变数据结构中的共享指针向量
- 阻止在返回时复制共享指针