3

执行以下代码时出现运行时错误:

#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;
}

我试图找出删除原始共享指针后指针是否仍然可以访问(不应该)。

4

2 回答 2

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>lock 会发生什么,你会得到一个包含 NULL 的 shared_ptr。((Test*)NULL)->value当你这样做时会发生什么,p->value这是一个明显的段错误。

拥有weak_ptr 的全部意义在于让用户能够安全地获取对可能超出范围的对象的引用。异常将是一个糟糕的机制,因为异常是缓慢的,如果weak_ptr的父级超出范围,它不一定是致命错误。所以机制是 lock 在提升时返回一个新的计数引用,或者如果它不能再提升所有权级别(父级已过期),则返回 NULL。

于 2014-04-02T21:26:38.197 回答
1

您可以阅读文档,而不是对事情的工作方式做出假设。

lock不通过抛出异常来表示空指针:它返回一个空指针。

所以,

        auto p = testList[i].lock();
        if( p != nullptr )
        {
            cout << "\n Item not null: " << p->value;
        }
        else
        {
            cout << "\n Item is null." << endl;
        }
于 2014-04-02T21:27:08.790 回答