다음을 통해 공유


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

shared_ptr 형식 시나리오는 두 개 이상의 소유자 메모리에 있는 개체의 수명을 관리 해야 할 설계 된 c + + 표준 라이브러리에서에 대 한 스마트 포인터입니다.초기화 후에 shared_ptr 복사 함수 인수를 값으로 전달 및 할당 다른 shared_ptr 인스턴스.모든 인스턴스가 동일한 개체를 가리키고 될 때마다 참조 횟수 "증가 하는 제어 블록" 하나 및 감소에 대 한 액세스를 공유 shared_ptr 추가, 범위를 벗어나게 되거나 다시 설정 됩니다.참조 횟수가 0이 되 면 제어 블록 메모리 리소스를 사용 하 고 자체를 삭제 합니다.

다음 그림에서는 몇 가지 보여 줍니다 shared_ptr 인스턴스는 메모리 위치를 가리킵니다.

공유 포인터

예제

가능 하면 사용을 make_shared (<memory>) 함수는 shared_ptr 메모리 리소스를 처음으로 만들 때.make_shared예외 안전성이 보장 됩니다.제어 블록 및 리소스에 대 한 메모리를 할당할 수 같은 호출을 사용 하 고 있으므로 생성 오버 헤드를 줄일 수 합니다.사용 하지 않는 경우 make_shared, 새 명시적 식에 전달 되기 전에 개체를 만드는 데 사용 하 고 있는 shared_ptr 생성자입니다.다음 예제에서는 선언 하 고 초기화 하는 방법을 보여 주는 한 shared_ptr 새 개체와 함께 합니다.


// Use make_shared function when possible.
auto sp1 = make_shared<Song>(L"The Beatles", L"Im Happy Just to Dance With You");

// Ok, but slightly less efficient. 
// Note: Using new expression as constructor argument
// creates no named variable for other code to access.
shared_ptr<Song> sp2(new Song(L"Lady Gaga", L"Just Dance"));

// When initialization must be separate from declaration, e.g. class members, 
// initialize with nullptr to make your programming intent explicit.
shared_ptr<Song> sp5(nullptr);
//Equivalent to: shared_ptr<Song> sp5;
//...
sp5 = make_shared<Song>(L"Elton John", L"I'm Still Standing");

다음 예제에서는 선언 하 고 초기화 하는 방법을 보여 줍니다. shared_ptr 에 인스턴스가 이미 다른 할당 된 개체의 소유권을 공유 shared_ptr.가정 sp2 는 초기화 되지 shared_ptr.

//Initialize with copy constructor. Increments ref count.
auto sp3(sp2);

//Initialize via assignment. Increments ref count.
auto sp4 = sp2;

//Initialize with nullptr. sp7 is empty.
shared_ptr<Song> sp7(nullptr);

// Initialize with another shared_ptr. sp1 and sp2
// swap pointers as well as ref counts.
sp1.swap(sp2);

shared_ptr요소를 복사 하는 알고리즘을 사용 하는 경우 또한 STL (표준 템플릿 라이브러리) 컨테이너에 유용 합니다.요소가 줄 바꿈될 수는 shared_ptr, 다른 컨테이너 내부 메모리가 필요할 때 유효 하 고 더 이상 임을 이해에 복사.다음 예제에서는 사용 하는 방법을 보여 줍니다 있는 replace_copy_if 알고리즘을 shared_ptr 벡터에 대 한 인스턴스.

vector<shared_ptr<Song>> v;

v.push_back(make_shared<Song>(L"Bob Dylan", L"The Times They Are A Changing"));
v.push_back(make_shared<Song>(L"Aretha Franklin", L"Bridge Over Troubled Water"));
v.push_back(make_shared<Song>(L"Thal�a", L"Entre El Mar y Una Estrella"));

vector<shared_ptr<Song>> v2;
remove_copy_if(v.begin(), v.end(), back_inserter(v2), [] (shared_ptr<Song> s) 
{
    return s->artist.compare(L"Bob Dylan") == 0;     
});


for_each(v2.begin(), v2.end(), [] (shared_ptr<Song> s)
{
    wcout << s->artist << L":" << s->title << endl;
});

You can use dynamic_pointer_cast, static_pointer_cast, and const_pointer_cast to cast a shared_ptr.유사 이러한 함수는 dynamic_cast, static_cast, 및 const_cast 운영자입니다.다음 예제에서는 벡터의 각 요소의 파생된 유형을 테스트 하는 방법을 보여 줍니다. shared_ptr 의 기본 클래스를 다음 요소를 복사 하 고 정보를 표시 합니다.

    vector<shared_ptr<MediaAsset>> assets;

    assets.push_back(shared_ptr<Song>(new Song(L"Himesh Reshammiya", L"Tera Surroor")));
    assets.push_back(shared_ptr<Song>(new Song(L"Penaz Masani", L"Tu Dil De De")));
    assets.push_back(shared_ptr<Photo>(new Photo(L"2011-04-06", L"Redmond, WA", L"Soccer field at Microsoft.")));

    vector<shared_ptr<MediaAsset>> photos;

    copy_if(assets.begin(), assets.end(), back_inserter(photos), [] (shared_ptr<MediaAsset> p) -> bool
    {
        // Use dynamic_pointer_cast to test whether
        // element is a shared_ptr<Photo>.
        shared_ptr<Photo> temp = dynamic_pointer_cast<Photo>(p);        
        return temp.get() != nullptr;
    });

    for_each(photos.begin(), photos.end(), [] (shared_ptr<MediaAsset> p)
    {
        // We know that the photos vector contains only 
        // shared_ptr<Photo> objects, so use static_cast.
        wcout << "Photo location: " << (static_pointer_cast<Photo>(p))->location_ << endl;
    });

전달할 수 있는 shared_ptr 다른 기능에 다음과 같은 방법으로:

  • 전달 된 shared_ptr 값입니다.이 복사 생성자를 호출, 참조 횟수를 증가 및 호출 수신자의 소유자 수 있습니다.약간의 오버 헤드는 상당한 수에 따라이 작업에는 shared_ptr 개체를 전달 합니다.호출자와 호출 수신자 사이의 코드 계약 (암시적 또는 명시적) 호출 수신자 소유자 이어야 하는 경우이 옵션을 사용 합니다.

  • 전달 된 shared_ptr 참조 또는 const 참조입니다.이 경우 참조 횟수가 증가 하지 않습니다, 및 호출자가 범위를 벗어나면 시작 하지 못할 때 호출 수신자 포인터에 액세스할 수 있습니다.또는 호출 수신자를 만들려면 결정할 수는 shared_ptr 참조에 기반 하 고 있으므로 소유자를 공유 됩니다.호출자가 호출 수신자를 전혀 없는 또는 통과 해야 할 경우이 옵션을 사용을 shared_ptr 및 성능상의 이유로 복사 작업을 방지 하려는.

  • 내부 포인터 또는 내부 개체에 대 한 참조를 전달 합니다.이 호출 수신자 개체를 사용할 수 있지만 소유권을 공유 하거나 수명을 연장할 수 없습니다.호출 수신자가 생성 하는 경우는 shared_ptr 원시 포인터에서 새 shared_ptr 원본에서 독립적 이며 기본 리소스를 제어 하지 않습니다.호출자에 게 소유권 호출자와 호출 수신자 사이의 계약을 명확 하 게 지정 하는 경우이 옵션을 사용 된 shared_ptr 수명.

  • 전달 하는 방법을 결정 되 면은 shared_ptr, 호출 수신자가 기본 리소스의 소유권을 공유할 수 있는지 여부를 확인 합니다."소유자" 개체나 필요한 것 처럼 내부 리소스에 대 한 활성 상태로 유지 수 있는 함수입니다.호출자가 호출 수신자를 외부로 포인터의 수명을 확장할 수 있는 보장 하는 경우 해당 수명 (함수), 첫 번째 옵션입니다.호출 수신자의 수명은 연장 여부 상관 없음 경우 참조로 전달 하 고 호출 수신자가 해당 인스턴스를 복사할 수 있습니다.

  • 하는 경우 내부 포인터를 하는 도우미 함수 액세스 도우미 함수 바로 포인터를 사용 하 고 반환 하 고 함수 호출 함수 반환 값 앞는 아는 게 내부 포인터의 소유권을 공유할 수 없습니다.방금 호출자의 수명 내에서 포인터를 액세스할 수 있는 shared_ptr.이 경우 안전 하 게 전달 되는 shared_ptr 개체 참조 또는 패스에서 원시 포인터 또는 내부에 대 한 참조입니다.이런 방식이으로 전달 하 여 작은 성능 이점을 제공 및 또한 프로그래밍 의도 표현할 수 있습니다.

  • 때때로, 예를 std:vector<shared_ptr<T>>, 각각 전달 할 수 있습니다 shared_ptr 람다 식 본문이 나 명명 된 함수 개체입니다.람다 또는 함수 포인터를 저장 하 고 경우 전달 된 shared_ptr 참조 하는 각 요소에 대 한 복사 생성자를 호출 하지 마십시오.

다음 예제를 보여 줍니다 어떻게 shared_ptr 소유 하 고 있는 메모리 포인터 비교를 사용할 수 있도록 다양 한 비교 연산자를 오버 로드 된 shared_ptr 인스턴스.


// Initialize two separate raw pointers.
// Note that they contain the same values.
auto song1 = new Song(L"Village People", L"YMCA");
auto song2 = new Song(L"Village People", L"YMCA");

// Create two unrelated shared_ptrs.
shared_ptr<Song> p1(song1);    
shared_ptr<Song> p2(song2);

// Unrelated shared_ptrs are never equal.
wcout << "p1 < p2 = " << std::boolalpha << (p1 < p2) << endl;
wcout << "p1 == p2 = " << std::boolalpha <<(p1 == p2) << endl;

// Related shared_ptr instances are always equal.
shared_ptr<Song> p3(p2);
wcout << "p3 == p2 = " << std::boolalpha << (p3 == p2) << endl; 

참고 항목

개념

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