Sdílet prostřednictvím


Implicitní zabalení typů hodnot

Zabalení typů hodnot se změnilo ze způsobů ze Správce rozšíření pro C++ na způsob z Visual C++ 2010.

V návrhu jazyka jsme ukládali filozofickou pozici namísto praktických zkušeností s funkcí a v praxi to byla chyba. Analogicky v originálním více dědičném návrhu jazyka, Stroustrup rozhodl, že podobjekt virtuální základní třídy nemohl být inicializován v rámci konstruktoru odvozené třídy a proto jazyk važadoval, že jakákoliv třída sloužící jako virtuální základní třída, musí být definována výchozím konstruktorem. Je to výchozí konstruktor, který bude vyvolávat jakékoli následné virtuální odvození.

Problémem hierarchie virtuální základní třídy je zodpovědný za inicializaci sdíleného virtuálního podobjektu, který se posune s každým následným odvozením. Například pokud definujeme základní třídu pro kterou vyžaduje inicializace přidělení do vyrovnávací paměti, uživatelem specifikovaná velikost vyrovnávací paměti může být předána jako argument do konstruktoru. Máme-li tedy poskytnut dvě po sobě jdoucí virtuální odvození, zavoláme inputb a outputb, každý obsahuje určitou hodnotu do konstruktoru základní třídy. Nyní, když odvodíme třídu in_out z obou inputb a outputb, ani jedna z těchto hodnot ze sdíleného virtuálního podobjektu základní třídy nemůže mít rozumnou možnost vyhodnocení.

Proto v původním návrhu jazyka, zakázal Stroustrup explicitní inicializaci virtuální základní třídy v rámci seznamu členské inicializace z konstruktoru odvozené třídy. Zatímco byl problém vyřešen, v praxi se neschopnost přímé inicializace virtuální základní třídy ukázala jako nepraktická. Keith Gorlen z National Institute of Health, který naimplementoval freeware verzi sady jazyků SmallTalk nazvané nihcl, měl zásadní rozhodnutí v přesvědčování Stroustrupa, že musí přijít s více flexibilnějším návrhem jazyka.

Princip objektově orientované hierarchie návrhu se zabývá tím, že odvozená třída by se měla zabývat pouze neprivátní implementací své přímé základní třídy. Za účelem podpory flexibilní inicializace návrhu pro virtuální dědičnost, porušil Stroustrup tuto zásadu. Většina odvozených tříd v hierarchii přebírá zodpovědnost za všechny inicializace virtuálních podobjektů bez ohledu na to, jak hluboko do hierarchie k ní dojde. Například inputb a outputb jsou odpovědné za explicitní inicializaci jejich přímé virtuální základní třídy. Při in_out odvození z obou inputb a outputb, bude in_out zodpovědná za inicializaci jedné odebráné virtuální základní třídy a explicitní inicializace v rámci inputb a outputb bude potlačena.

To poskytuje flexibilitu požadovanou vývojáři jazyka, ale na druhou stranu složitou sémantiku. Této komplikace se zbavíme, pokud jsme omezili virtuální základní třídu bez stavu a jednoduše ji umožnili zadání rozhraní. Toto je doporučený návrhový idiom, v rámci jazyka C++. V rámci programování CLR jsou zvyšovány zásady s typem rozhraní.

Zde je jednoduchý kód sample– a v takovém případě je zbytečné explicitní zabalení:

// Managed Extensions for C++ requires explicit __box operation
int my1DIntArray __gc[] = { 1, 2, 3, 4, 5 };
Object* myObjArray __gc[] = { 
   __box(26), __box(27), __box(28), __box(29), __box(30)
};

Console::WriteLine( "{0}\t{1}\t{2}", __box(0),
   __box(my1DIntArray->GetLowerBound(0)),
   __box(my1DIntArray->GetUpperBound(0)) );

Jak můžete vidět, je celé velké množství zabalení pryč. Ve Visual C++ 2010, je zabalení typu hodnoty implicitní:

// new syntax makes boxing implicit
array<int>^ my1DIntArray = {1,2,3,4,5};
array<Object^>^ myObjArray = {26,27,28,29,30};

Console::WriteLine( "{0}\t{1}\t{2}", 0, 
   my1DIntArray->GetLowerBound( 0 ), 
   my1DIntArray->GetUpperBound( 0 ) );

Viz také

Odkaz

Implicit Boxing

Koncepty

Typy hodnot a jejich chování