我开始研究C++ 11的智能指针,我没有看到任何有用的用法std::weak_ptr.有人能告诉我什么时候std::weak_ptr有用/必要吗?
我正在阅读Scott Meyers的"Effective C++"一书.有人提到有内置指针tr1::shared_ptr和tr1::weak_ptr行为,但它们跟踪tr1::shared_ptrs指向对象的数量.
这称为引用计数.这在防止非循环数据结构中的资源泄漏方面效果很好,但是如果两个或多个对象包含tr1::shared_ptrs形成循环,则循环可以使彼此的引用计数保持在零以上,即使所有指向循环的外部指针都已被破坏.
那是tr1::weak_ptrs进来的地方.
我的问题是循环数据结构如何使引用计数高于零.我恳请一个示例C++程序.问题是如何解决的weak_ptrs?(再次,请举例).
我理解如何使用weak_ptr和shared_ptr.我shared_ptr通过计算其对象中的引用数来理解它是如何工作的.weak_ptr工作怎么样?我尝试阅读boost源代码,并且我不熟悉boost以了解它使用的所有内容.
谢谢.
如果我理解正确,a weak_ptr不会增加托管对象的引用计数,因此它不代表所有权.它只是让您访问一个对象,其生命周期由其他人管理.所以我真的不明白为什么一个weak_ptr不能用a构建unique_ptr,而只能用a 构建shared_ptr.
有人能简单解释一下吗?
在我目前的项目中,我使用boost::shared_ptr得非常广泛.
最近我的队友们也开始使用了weak_ptr.我不知道使用哪一个以及何时使用.
除此之外,如果我想转换weak_ptr为,我该怎么办shared_ptr?是否锁定在其他线程中weak_ptr创建shared_ptr影响我的代码?
我在shared_ptr和weak_ptr一起使用时遇到了麻烦enable_shared_from_this。
当我用Google搜索所见事物的症状时,每个人都建议“ shared_from_this()当没有shared_ptr实例拥有您的对象时,您将无法使用。
但这不是我的情况。
考虑以下代码:
#include <memory>
#include <cassert>
class MyClass : std::enable_shared_from_this<MyClass>
{
public:
void this_fails()
{
// Doesn't even assert(), because it throws bad_weak_ptr
assert(shared_from_this());
}
void this_fails_too()
{
std::weak_ptr<MyClass> weak = weak_from_this();
std::shared_ptr<MyClass> strong = weak.lock();
// This assert fails
assert(strong.get());
}
};
int main()
{
std::shared_ptr<MyClass> obj = std::make_shared<MyClass>();
obj->this_fails();
obj->this_fails_too();
}
Run Code Online (Sandbox Code Playgroud)
两种方法都会MyClass使程序崩溃。我一定缺少明显的东西-这是什么?
c++ shared-ptr weak-ptr private-inheritance enable-shared-from-this
我想比较两个std :: weak_ptr或一个std :: weak_ptr和一个std :: shared_ptr的相等性.
我想知道的是weak_ptr/shared_ptr指向的每个对象是否相同.比较应该产生负面结果,不仅如果地址不匹配,而且如果基础对象被删除然后偶然使用相同地址重建.
所以基本上,即使分配器保留相同的地址,我也希望这个断言成立:
auto s1 = std::make_shared<int>(43);
std::weak_ptr<int> w1(s1);
s1.reset();
auto s2 = std::make_shared<int>(41);
std::weak_ptr<int> w2(s2);
assert(!equals(w1,w2));
Run Code Online (Sandbox Code Playgroud)
weak_ptr模板不提供相等的运算符,正如我所理解的那样,这是有充分理由的.
所以一个天真的实现看起来像这样:
template <typename T, typename U>
inline bool naive_equals(const std::weak_ptr<T>& t, const std::weak_ptr<U>& u)
{
return !t.expired() && t.lock() == u.lock();
}
template <typename T, typename U>
inline bool naive_equals(const std::weak_ptr<T>& t, const std::shared_ptr<U>& u)
{
return !t.expired() && t.lock() == u;
}
Run Code Online (Sandbox Code Playgroud)
如果第一个weak_ptr在此期间到期,则它会产生0.如果不是,我将weak_ptr升级为shared_ptr并比较地址.
这个问题是我必须锁定weak_ptr两次(一次)!我担心花费太多时间.
我想出了这个:
template <typename T, typename U>
inline bool equals(const …Run Code Online (Sandbox Code Playgroud) 我正在为游戏设计一个对象结构,在我的案例中,最自然的组织变成了一棵树.作为智能指针的忠实粉丝我shared_ptr独家使用.但是,在这种情况下,树中的孩子将需要访问它的父母(例如 - 地图上的生物需要能够访问地图数据 - 他们的父母的数据.
拥有的方向当然是地图拥有它的存在,所以拥有它们的共享指针.要从存在中访问地图数据,我们需要一个指向父节点的指针 - 智能指针的方式是使用引用,ergo a weak_ptr.
然而,我曾经读到锁定a weak_ptr是一项昂贵的操作 - 可能这不再是真的 - 但考虑到weak_ptr它将经常被锁定,我担心这种设计注定会失败.
因此问题是:
锁定weak_ptr会有什么性能损失?它有多重要?
C++ 11的std :: shared_ptr <>提供了一种bool运算符.
operator unspecified-bool-type() const;
Run Code Online (Sandbox Code Playgroud)
(operator bool() const由于类型的隐式转换带来的危险,这不是直接的bool.)
为什么std :: weak_ptr <>没有类似的运算符?我发现自己经常打字
if( !wp.expired() )
Run Code Online (Sandbox Code Playgroud)
当我想打字的时候
if( wp )
Run Code Online (Sandbox Code Playgroud)
为什么没有针对weak_ptr的bool转换?
c++ ×10
weak-ptr ×10
shared-ptr ×7
c++11 ×4
boost ×3
performance ×1
raw-pointer ×1
tr1 ×1
unique-ptr ×1