我有一个课程,我知道总是归std::shared_ptr
所有。但是,将shared_ptr
甚至weak_ptr
传递给不需要所有权或终身保证的函数和方法会产生不必要的开销。为了解决这个问题,我经常将原始指针传递给函数。类本身继承自std::enable_shared_from_this
,因此如果函数需要获取指针的所有权,它可以使用类的方法来获取shared_ptr
。
这一切都很美妙。但有时候我并不想从原始指针中创建shared_ptr
,我想要的只是weak_ptr
。
根据我对std::shared_ptr
的通常实现的理解,它有两个原子变量用作参考计数器;一个用于shared_ptr
,一个用于weak_ptr
。
如果我只有一个指向我班级的原始指针而我想要一个weak_ptr
,我必须首先创建一个shared_ptr
并将其转换。这样做意味着参考计数器的改变如下:
shared_ptr
,增加shared_ptr
计数器weak_ptr
,增加weak_ptr
计数器shared_ptr
超出范围,递减shared_ptr
计数器这似乎违背了这样的想法:"你不会为你不能使用的东西买单"。有没有办法让我的班级只提供weak_ptr
而无需先创建shared_ptr
?
答案 0 :(得分:9)
2015年10月的会议中,C ++ 17接受了提案P0033,该会议将weak_from_this
添加到源自std::enable_shared_from_this
的类中。
答案 1 :(得分:6)
我是否有办法在没有首先创建shared_ptr的情况下提供weak_ptr?
不在C ++ 14中; enable_shared_from_this
支持的唯一操作是创建shared_ptr
。现在,enable_shared_from_this
应该有足够的信息来直接构建weak_ptr
。但是你不能从外面做,因为班级没有向你公开其实施细节。
C ++ 17支持通过weak_ptr
从enable_shared_from_this
课程中提取weak_from_this
。
答案 2 :(得分:3)
实施它几乎是微不足道的,不值得放入图书馆......
#include <memory>
template<class T> std::weak_ptr<T> weak_from_this(T*p) {
return { p->shared_from_this() };
}
struct S : std::enable_shared_from_this<S>
{
auto foo() {
return weak_from_this(this);
}
};
int main()
{
auto ps = std::make_shared<S>();
auto wps = ps->foo();
}