执行以下代码时出现运行时错误:
#include <iostream>
#include <vector>
#include <memory>
using namespace std;
class Test
{
public:
int value;
Test( )
{
value = 1;
}
~Test( )
{
}
};
int main() {
shared_ptr<Test> pTest = shared_ptr<Test>( new Test( ) );
std::vector<weak_ptr<Test>> testList;
testList.push_back( weak_ptr<Test>(pTest) );
cout << "\n Before Deletion";
for (unsigned int i=0; i < testList.size(); i++)
{
try
{
auto p = testList[i].lock();
cout << "\n Item not null: " << p->value;
}
catch (bad_weak_ptr b)
{
wcout << L"Null object" << endl;
}
}
pTest.reset( );
cout << "\n After Deletion";
for (unsigned int i=0; i < testList.size(); i++)
{
try
{
auto p = testList[i].lock();
cout << "\n Item not null: " << p->value;
}
catch (bad_weak_ptr b)
{
wcout << L"Null object" << endl;
}
}
// your code goes here
return 0;
}
在删除原始共享指针后,我试图找出指针是否仍然可访问(不应该)。
答案 0 :(得分:2)
Lock不检查null,它将weak_ptr提升为共享指针。删除对象时它不会抛出,而是返回null。
这就是你应该做的。
#include <iostream>
#include <vector>
#include <memory>
using namespace std;
class Test
{
public:
int value;
Test( )
{
value = 1;
}
~Test( )
{
}
};
int main() {
shared_ptr<Test> pTest = shared_ptr<Test>( new Test( ) );
std::vector<weak_ptr<Test>> testList;
testList.push_back( weak_ptr<Test>(pTest) );
cout << "\n Before Deletion";
for (unsigned int i=0; i < testList.size(); i++)
{
auto p = testList[i].lock();
if (p)
{
cout << "\n Item not null: " << p->value;
}
else
{
wcout << L"Null object" << endl;
}
}
pTest.reset( );
cout << "\n After Deletion";
for (unsigned int i=0; i < testList.size(); i++)
{
auto p = testList[i].lock();
if (p)
{
cout << "\n Item not null: " << p->value;
}
else
{
wcout << L"Null object" << endl;
}
}
// your code goes here
return 0;
}
为了澄清一下,当pTest重置后你在test_list&gt;锁定时会发生什么,你会得到一个包含NULL的shared_ptr。而((Test*)NULL)->value
是p->value
发生的事情,这是一个明显的段错误。
拥有weak_ptr的重点是允许用户安全地获取对可能超出范围的对象的引用。异常对此来说是一个糟糕的机制,因为异常是缓慢的,如果weak_ptr的父级超出范围,则不一定是致命的错误。因此,锁定机制或者在提升时返回新的计数引用,如果它不再提升所有权级别(父级已经过期),则返回NULL。
答案 1 :(得分:1)
您可以 read the documentation ,而不是假设事情是如何运作的。
lock
不会通过抛出异常来表示nullpointer:它返回一个nullpointer。
所以,
auto p = testList[i].lock();
if( p != nullptr )
{
cout << "\n Item not null: " << p->value;
}
else
{
cout << "\n Item is null." << endl;
}