jnb*_*mez 16 c++ shared-ptr weak-ptr c++11 c++14
请考虑以下代码:
#include <iostream>
#include <memory>
using namespace std;
class T;
std::weak_ptr<T> wptr;
class T
{
public:
T() { }
~T() {
std::cout << "in dtor" << std::endl;
std::cout << (wptr.expired() ? "expired" : "not expired") << std::endl;
}
};
int main() {
{
auto ptr = std::make_shared<T>();
wptr = ptr;
std::cout << (wptr.expired() ? "expired" : "not expired") << std::endl;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在这段代码中,我试图找出weak_ptrs在对象销毁阶段是否过期.看来是这样.输出是:
not expired
in dtor
expired
Run Code Online (Sandbox Code Playgroud)
我用gcc-5.1和ideone.
现在,我有另一个问题.我找不到任何文档说明这是标准行为.难道是保证这样的工作方式,始终?
现在,我有另一个问题.我找不到任何文档说明这是标准行为.难道是保证这样的工作方式,始终?
实际上,正如LWG第2751号提出的那样,它在标准中没有明确规定.
C++ 14标准不包含任何语言,该语言保证由a运行的删除器
shared_ptr将所有关联的weak_ptr实例视为已过期.例如,标准似乎不保证以下代码段中的断言不会触发:Run Code Online (Sandbox Code Playgroud)std::weak_ptr<Foo> weak; std::shared_ptr<Foo> strong{ new Foo, [&weak] (Foo* f) { assert(weak.expired()); delete f; }, }; weak = strong; strong.reset();似乎很清楚,意图是关联的
weak_ptrs已过期,因为否则shared_ptr删除者可以恢复对正被删除的对象的引用.建议修复:23.11.3.2 [util.smartptr.shared.dest]应指定
use_count()在调用删除器或调用之前对析构函数引起的减少进行排序delete p.
~shared_ptr()上面链接的当前措辞仅表示调用删除器,非规范性说明共享所有权的实例数量减少.
虽然意图可能是weak.expired()在调用删除器时,依赖于此是有问题的.shared_ptr确切地说,在它被摧毁之后不再拥有所有权是真的是合理的 - 在破坏期间询问这个问题有点奇怪.
像这样使用make_shared将使用您提供的默认构造函数创建一个对象.
template< class T, class... Args >
shared_ptr<T> make_shared( Args&&... args );
Run Code Online (Sandbox Code Playgroud)
构造一个T类型的对象,并将其包装在一个
std::shared_ptrusing args中作为T的构造函数的参数列表.该对象就像表达式一样构造(std :: make_shared)
在主要的匿名范围之后.共享的ptr将被删除.
当发生以下任一情况时,对象将被销毁并释放其内存:
拥有该对象的最后剩余的shared_ptr被销毁; (std :: shared_ptr)
.
shared_ptr的析构函数减少控制块的共享所有者的数量.如果该计数器达到零,则控制块将调用托管对象的析构函数.在std :: weak_ptr计数器也达到零之前,控制块不会解除分配.std :: shared_ptr实施说明
这意味着您的对象将在最后一个共享ptr的破坏开始后调用其析构函数.输出:
not expired
in dtor
expired
Run Code Online (Sandbox Code Playgroud)
是预期的行为.
不是标准本身,而是:
\n\nhttp://en.cppreference.com/w/cpp/memory/weak_ptr/expired
\n\n\n\n\n检查管理对象是否已被删除。相当于\n use_count() == 0。
\n
use_count所以这就变成了删除之前或之后天气设置为0的问题。现在标准草案中没有提到这一点:\n http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3690.pdf [第 566 页 20.9.2.2 .2]
\n\n\n\n
~shared_ptr();效果:
\n\n\n
\n\n- 如果
\n*this为空或与另一个shared_ptr实例共享所有权 (use_count() > 1),则没有副作用。- 否则,如果
\n*this拥有一个对象p和一个删除器d,d(p)则被调用。- 否则,
\n*this拥有一个指针p,并被delete p调用。[注意:由于 的销毁会使
\n*this共享所有权的实例数量减少 1*this,因此在*this销毁后,所有与其shared_ptr共享所有权的实例*this将报告use_count()比之前的值少 1 的值。\xe2\x80\x94 尾注]