====== Boost::value_initialized ====== **Rafał Wilk** ===== Wstęp ===== Boost::value_initialized 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: T zmienna; 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: T zmienna = 0; T klasa = T(); 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: value_initialized zmienna; 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 ===== Oto jak wygląda klasa value_initialized: template class value_initialized { public : value_initialized() : x() {} operator T&() const { return x ; } T& data() const { return x ; } private : unspecified x ; } 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 &x ), która także pozwala na dostęp do referencji obiektu. template T const& get ( value_initialized const& x ) { return x.data() ; } template T& get ( value_initialized& x ) { return x.data() ; } Co daje łącznie trzy możliwości otzrymania referencji do obiektu i wykorzystania jej: void fun(&T); value_initialized zmienna; fun(zmienna); fun(zmienna.data()); fun(get(zmienna)); 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ż: value_initialized zmienna ; get(zmienna) = 1 ; // poprawne value_initialized const_zmienna ; get(const_zmienna) = 1 ; // błąd: obiekt typu const value_initialized const zmienna_const ; get(zmienna_const) = 1 ; // błąd: obiekt typu const value_initialized const const_zmienna_const ; get(const_zmienna_const) = 1 ; // błąd: obiekt typu const ===== 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.