Narzędzia użytkownika

Narzędzia witryny


value_initialized

Różnice

Różnice między wybraną wersją a wersją aktualną.

Odnośnik do tego porównania

value_initialized [2009/04/30 00:02] (aktualna)
rwilk utworzono
Linia 1: Linia 1:
 +====== Boost::​value_initialized<​T>​ ======
  
 +**Rafał Wilk**
 +===== Wstęp =====
 +
 +Boost::​value_initialized<​T>​ zapewnia generyczny sposób inicjacji deklarowanych zmiennych, klas, wskaźników i innych typów. Korzystanie z value_initialized zapewnia zinicjowanie zdeklarowanego typu wartością domyślną w momencie deklaracji.  ​
 +
 +===== Funkcjonalność =====
 +
 +Zadeklarować zmienną można na wiele różnych sposobów, ale nie zawsze wartość zadeklarowanej zmiennej jest oczywista.
 +
 +Przykładowo:​
 +
 +<​code>​
 +T zmienna;
 +</​code>​
 +
 +Powyższa deklaracja nie determinuje wartości zadeklarowanej zmiennej,​(często w zależności od systemu operacyjnego) zmienna ta może zostać zainicjowana wartością domyślną lub też pozostawiona z wartością bliżej nie określoną.
 +
 +Można próbować na inne sposoby:
 +
 +<​code>​
 +T zmienna = 0;
 +T klasa = T();
 +</​code>​
 +
 +W tym wypadku pierwszy przykład poprawnie zainicjuje zmienną lecz nie poradzi sobie z inicjacją klasy. Drugi przykład nie może być stosowany dla klas, które dziedziczą po boost::​noncopyable lub mają prywatny lub niezdefiniowany konstruktor kopiujący.
 +
 +W tych wszystkich przypadkach swoje zastosowanie znajduje value_initialized:​
 +
 +<​code>​
 +value_initialized<​T>​ zmienna;
 +</​code>​
 +
 +Zapewnia inicjację wartością domyślną, 0 dla zmiennych artymetycznych,​ null'​em dla wskaźników,​ wartością false dla typu bool, wykorzystuje domyślny konstruktor klasy itd..   
 +
 +===== Klasa value_initialized<​T>​ =====
 +
 +Oto jak wygląda klasa value_initialized:​
 +
 +<​code>​
 +template<​class T>
 +class value_initialized
 +{
 +  public :
 +    value_initialized() : x() {}
 +    operator T&() const { return x ; }
 +    T& data() const { return x ; }
 +
 +  private :
 +    unspecified x ;
 +
 +</​code>​
 +
 +Udostepnia ona dwie możliwości dostępu do referencji do przechowywanego obiektu: operator T&() oraz metodę T& data().
 +
 +Dodatkowo zdefiniowane została funkcja T& get( value_initialized<​T>​ &x ), która także pozwala na dostęp do referencji obiektu.
 +
 +<​code>​
 +template<​class T>
 +T const& get ( value_initialized<​T>​ const& x )
 +{
 +  return x.data() ;
 +}
 +
 +template<​class T>
 +T& get ( value_initialized<​T>&​ x )
 +{
 +  return x.data() ;
 +}
 +</​code>​
 +
 +Co daje łącznie trzy możliwości otzrymania referencji do obiektu i wykorzystania jej:
 +
 +<​code>​
 +void fun(&​T);​
 +value_initialized<​T>​ zmienna;
 +
 +fun(zmienna);​
 +fun(zmienna.data());​
 +fun(get(zmienna));​
 +</​code>​
 +
 +Ze względu na dwie wersje funkcji get, dla wartości zmiennych i const, zaleca się właśnie ten sposób dostępu do referencji. Zapewniona zostaje kontrola dostępu i dlatego też:
 +
 +<​code>​
 +value_initialized<​int>​ zmienna ;
 +get(zmienna) = 1 ; // poprawne
 +
 +value_initialized<​int const> const_zmienna ;
 +get(const_zmienna) = 1 ; // błąd: obiekt typu const
 +
 +value_initialized<​int>​ const zmienna_const ;
 +get(zmienna_const) = 1 ; // błąd: obiekt typu const
 +
 +value_initialized<​int const> const const_zmienna_const ;
 +get(const_zmienna_const) = 1 ; // błąd: obiekt typu const
 +</​code>​
 +
 +===== Przydatne zastosowania =====
 +
 +value_initialized znajdzie wiele możliwości by ułatwić życie programiście,​ nie jest natomiast narzędziem,​ bez k†órego nie można żyć.
 +
 +Przydatnym może okazać się inicjacja w miejscu deklaracji:
 +
 +1. klas dziedziczących po boost::​noncopyable lub z prywatnym konstruktorem kopiującym,​
 +
 +2. zmiennych arytmetycznych wartością zero,
 +
 +3. wskaźników wartością null,
 +
 +4. i pewnie wiele innych w zależności od potrzeb.
 + 
value_initialized.txt · ostatnio zmienione: 2009/04/30 00:02 przez rwilk