다음을 통해 공유


방법: 만들고 weak_ptr 인스턴스를 사용 합니다.

때로는 내부 개체에 액세스할 수 있는 방법을 개체를 저장 해야 있는 shared_ptr 없이 참조 횟수가 증가 합니다.간의 순환 참조 하는 경우 일반적으로 이런 shared_ptr 인스턴스.

최상의 디자인 가능 포인터의 소유권을 공유를 하지 않는 것입니다.그러나, 소유권을 공유 해야 하는 경우 shared_ptr 인스턴스 간의 순환 참조를 방지 합니다.불가피 한, 또는 심지어는 순환 참조를 어떤 이유로 되 면 사용 weak_ptr 하나 이상의 소유자는 약한 주려면 참조 다른 shared_ptr.사용 하는 weak_ptr, 만들 수 있습니다는 shared_ptr 는 조인만 관련 인스턴스의 기존 집합에 기본 메모리 리소스를 여전히 유효한 경우.A weak_ptr 자체 참조 횟수 참여 하지 않는 및 따라서이 참조 횟수가 0으로 이동 하지 못할 수 없습니다.그러나 사용할 수 있는 weak_ptr 의 새 복사본을 확보 하는 shared_ptr 를 초기화 했습니다.메모리가 이미 삭제 된 경우는 bad_weak_ptr 예외가 throw 됩니다.메모리 여전히 유효한 경우, 새 공유 포인터 참조 횟수가 증가 하 고 메모리 사용할 수 있습니다으로 shared_ptr 변수는 범위에 남아 있습니다.

예제

다음 코드 예제는 대/소문자 표시 위치 weak_ptr 순환 의존 관계가 있는 개체의 적절 한 삭제를 확인 하는 데 사용 됩니다.이 예제를 검토 하다 대체 솔루션만 간주 된 후 작성 된 가정 합니다.Controller 개체는 시스템 프로세스의 일부 측면을 나타냅니다와 독립적으로 작동 합니다.각 컨트롤러는 언제 든 지 다른 컨트롤러의 상태를 쿼리할 수 있어야 하 고 각 개인을 포함 vector<weak_ptr<Controller>> 이 목적입니다.각 벡터에 대 한 순환 참조가 있으므로, weak_ptr 인스턴스 대신 사용 shared_ptr.

#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;


class Controller 
{
public:
    int Num;
    wstring Status;
    vector<weak_ptr< Controller >> others;
    explicit Controller(int i) : Num(i) , Status(L"On")
    {
        wcout << L"Creating Controller" << Num << endl;
    }

    ~Controller()
    {
        wcout << L"Destroying Controller" << Num << endl;
    }

    // Demonstrates how to test whether the 
    // pointed-to memory still exists or not.
    void CheckStatuses() const
    {
        for_each(others.begin(), others.end(), [] (weak_ptr<Controller> wp)
        {
            try
            {
                auto p = wp.lock();
                wcout << L"Status of " << p->Num << " = " << p->Status << endl;
            }

            catch (bad_weak_ptr b)
            {
                wcout << L"Null object" << endl;
            }                
        });
    }
};

void RunTest()
{
    vector<shared_ptr< Controller >> v;
    v.push_back(shared_ptr< Controller >(new Controller(0)));
    v.push_back(shared_ptr< Controller > (new Controller(1)));
    v.push_back(shared_ptr< Controller > (new Controller(2)));
    v.push_back(shared_ptr< Controller > (new Controller(3)));
    v.push_back(shared_ptr< Controller > (new Controller(4)));

    // Each controller depends on all others not being deleted.
    // Give each controller a pointer to all the others.
    for (int i = 0 ; i < v.size(); i++)
    {
        for_each(v.begin(), v.end(), [v,i] (shared_ptr<Controller> p)
        {
            if(p->Num != i)
            {
                v[i]->others.push_back(weak_ptr<Controller>(p));
                wcout << L"push_back to v[" << i << "]: " << p->Num << endl;
            }
        });        
    }

    for_each(v.begin(), v.end(), [](shared_ptr<Controller>& p)
    {
        wcout << L"use_count = " << p.use_count() << endl;
        p->CheckStatuses();
    });
}

int main()
{    
    RunTest(); 
    wcout << L"Press any key" << endl;
    char ch;
    cin.getline(&ch, 1);
}

벡터는 실험으로 수정 others 에 vector<shared_ptr<Controller>>, 다음 출력에서 소멸자가 호출 하는 것을 확인 하 고 때 TestRun 반환 합니다.

참고 항목

개념

스마트 포인터 (현대 C++)