Składnia
#include <memory>
namespace std
{
template < class T >
class shared_ptr
{
};
}
Opis szczegółowy
Szablon klasy, którego zadaniem jest zliczanie liczby referencji dla dynamicznie zaalokowanego obiektu. Zaalokowany obiekt jest natychmiast zwalniany z chwilą, gdy licznik referencji osiągnie wartość zero, tj. gdy ostatnia istniejąca referencja zostanie zniszczona.
Szablon klasy
std::shared_ptr gwarantuje, że liczba referencji będzie zawsze prawidłowa, zarówno w aplikacjach sekwencyjnych, jak również w aplikacjach wielowątkowych. Dzięki temu programista ma gwarancję, że obiekt trzymany za pomocą
std::shared_ptr zostanie zawsze poprawnie zwolniony.
Czy wiesz, że?
Szablon klasy std::shared_ptr prawidłowo zlicza referencje w aplikacjach wielowątkowych.
|
Przykłady
Prosty przykład użycia std::shared_ptr
#include <memory>
#include <cstdio>
int main()
{
typedef std::shared_ptr < int > REF_Int;
REF_Int refLiczba1;
{
REF_Int refLiczba2( new int( 123 ) );
printf( "Liczba referencji (refLiczba1) = %d\n", refLiczba1.use_count() );
printf( "Liczba referencji (refLiczba2) = %d\n", refLiczba2.use_count() );
refLiczba1 = refLiczba2;
printf( "Wartosc (refLiczba2) = %d\n", * refLiczba2 );
* refLiczba2 = 456;
printf( "refLiczba1 = refLiczba2;\n" );
printf( "Liczba referencji (refLiczba1) = %d\n", refLiczba1.use_count() );
printf( "Liczba referencji (refLiczba2) = %d\n", refLiczba2.use_count() );
printf( "Wychodze ze scope-a...\n" );
}
printf( "Liczba referencji (refLiczba1) = %d\n", refLiczba1.use_count() );
printf( "Wartosc (refLiczba1) = %d\n", * refLiczba1 );
return 0;
}
Standardowe wyjście programu:
Liczba referencji (refLiczba1) = 0
Liczba referencji (refLiczba2) = 1
Wartosc (refLiczba2) = 123
refLiczba1 = refLiczba2;
Liczba referencji (refLiczba1) = 2
Liczba referencji (refLiczba2) = 2
Wychodze ze scope-a...
Liczba referencji (refLiczba1) = 1
Wartosc (refLiczba1) = 456
Zliczanie referencji w aplikacji wielowątkowej
Poniższy kod prezentuje poprawne działanie zliczania referencji dla wskaźnika typu
std::shared_ptr w aplikacji wielowątkowej.
#include <memory>
#include <thread>
#include <cstdio>
#include <vector>
#include <sstream>
class CObiekt
{
public:
CObiekt()
: m_iCounter( 0 )
{
printf( "Konstruktor\n" );
}
void inc()
{
++m_iCounter;
}
virtual ~CObiekt()
{
printf( "Destruktor (%d)\n", m_iCounter );
}
private:
int m_iCounter;
};
typedef std::shared_ptr < CObiekt > REF_Obiekt;
void zonglowanieSharedPtr( std::shared_ptr < CObiekt >& refObiekt )
{
std::stringstream sThreadName;
sThreadName << std::this_thread::get_id();
printf( "[ID = %s] Thread created!\n", sThreadName.str().c_str() );
for( int i = 0; i < 10000; ++i )
{
REF_Obiekt obiekt = refObiekt;
obiekt->inc();
}
printf( "[ID = %s] Closing thread!\n", sThreadName.str().c_str() );
}
int main()
{
REF_Obiekt ref_value( new CObiekt() );
std::vector < std::thread > vThreads;
for( int i = 0; i < 10; ++i )
{
vThreads.push_back( std::thread( zonglowanieSharedPtr, ref_value ) );
printf( "Liczba referencji = %d\n", ref_value.use_count() );
}
zonglowanieSharedPtr( ref_value );
for( auto & item: vThreads )
item.join();
printf( "Liczba referencji = %d ( wartosc 1 oznacza poprawna liczbe referencji )\n", ref_value.use_count() );
return 0;
}
Możliwe standardowe wyjście programu:
Konstruktor
Liczba referencji = 2
[ID = 7028] Thread created!
[ID = 7028] Closing thread!
[ID = 7032] Thread created!
[ID = 7032] Closing thread!
Liczba referencji = 2
Liczba referencji = 2
[ID = 7036] Thread created!
Liczba referencji = 3
Liczba referencji = 5
[ID = 7036] Closing thread!
Liczba referencji = 4
[ID = 7040] Thread created!
[ID = 7048] Thread created!
[ID = 7044] Thread created!
[ID = 7040] Closing thread!
[ID = 7044] Closing thread!
[ID = 7048] Closing thread!
Liczba referencji = 5
[ID = 7052] Thread created!
Liczba referencji = 3
Liczba referencji = 4
[ID = 7052] Closing thread!
[ID = 7060] Thread created!
[ID = 7064] Thread created!
[ID = 7056] Thread created!
[ID = 7060] Closing thread!
Liczba referencji = 5
[ID = 7016] Thread created!
[ID = 7064] Closing thread!
[ID = 7056] Closing thread!
[ID = 7016] Closing thread!
Liczba referencji = 1 ( wartosc 1 oznacza poprawna liczbe referencji )
Destruktor (97263)
Linki zewnętrzne
Wszystkie teksty są chronione prawami autorskimi. Kopiowanie lub rozpowszechnianie treści poza niniejszym serwisem
jest zabronione.
Powyższe ograniczenie nie dotyczy autora opracowania, któremu przysługuje prawo do rozpowszechniania własnego tekstu wedle własnego uznania.