use*_*061 6 c++ shared-ptr weak-ptr c++11
当shared_ptr重置为包含的同一地址时,是否可以保证weak_ptr将过期?
#include <cassert>
#include <memory>
int main()
{
int* i = new int(0);
std::shared_ptr<int> si( i );
std::weak_ptr<int> wi = si;
si.reset( i );
assert( wi.expired() ); // wi.expired() == true (GCC 4.7)
}
Run Code Online (Sandbox Code Playgroud)
或者,当wi.expired()
未定义值时是这种情况?
编辑:
我现在稍微修改一下这个问题:
是否保证weak_ptr
在shared_ptr
重置到同一地址时会过期,该地址包含shared_ptr
初始化时的地址weak_ptr
?
#include <cassert>
#include <memory>
int main()
{
int* i = new int(0);
std::shared_ptr<int> si( i );
std::weak_ptr<int> wi = si;
si.reset();
int* j = new int(0);
// Suppose that new returns the same address that contains variable i :
assert(j == i);
si.reset( j );
assert( wi.expired() ); // wi.expired() == true (GCC 4.7)
}
Run Code Online (Sandbox Code Playgroud)
Sig*_*ndo 11
一方面,它实际应该.另一方面,将相同的指针分配给两个不同的共享指针(si-before-reset和si-after-reset)是不正确的.实际上,调用si.reset(i)
它会发生:
si
降至0delete i
被调用si
指向i
.所以i
复位后新分配的将指向未分配的内存,并且wi
正确到期(并且当si
它消失时会产生段错误,最终会i
再次尝试删除).
好的做法是在将裸指针分配给shared_ptr之后永远不要引用它.
编辑后的答案:
这同样适用:指针相同的事实与shared_ptr及其内部引用计数无关.对于一个"邪恶"的例子,这可能更清楚.这是错的:
int *i = new int;
std::shared_ptr<int> si1(i);
std::shared_ptr<int> si2(i); // deleting twice i on destruction of si2 - boom!
std::weak_ptr<int> wi1 = si1;
si1.reset();
assert (wi1.expired()); // true
Run Code Online (Sandbox Code Playgroud)
这与你的第一个例子类似(实际上是相同的):si1和si2是两个不同的shared_ptr(它们是si-before-reset和si-after-reset).si1
和si2
(错误地)指向同一个内存的事实与shared_ptr和连接的weak_ptr的生命无关.
i
指针的绝对值不用于确定引用计数.对于shared_ptr和weak_ptr都是如此.所以,是的,保证!
事实上,当你需要来自其类中的对象的shared_ptr时,你需要enable_shared_from_this - 如果你使用shared_ptr(this)
而不是shared_from_this ()你每次都会得到不同的shared_ptr - 一旦它们第一次出去就摧毁你的对象重新计数.
归档时间: |
|
查看次数: |
661 次 |
最近记录: |