Výkaz pomocou menného priestoru std sa všeobecne považuje za zlú prax. Alternatívou k tomuto príkazu je špecifikovať menný priestor, do ktorého identifikátor patrí, pomocou operátora rozsahu (::) zakaždým, keď deklarujeme typ.
Hoci výpis nás šetrí od písania std:: vždy, keď chceme získať prístup k triede alebo typu definovanému v mennom priestore std, importuje sa celý std menný priestor do aktuálneho menného priestoru programu. Uveďme si niekoľko príkladov, aby sme pochopili, prečo to nemusí byť také dobré
Povedzme, že chceme použiť cout z menného priestoru std. Tak píšeme
Príklad 1:
CPP
#include> using> namespace> std;> > cout <<>' Something to Display'>;> |
>
>
Teraz v neskoršom štádiu vývoja chceme použiť inú verziu cout, ktorá je implementovaná na mieru v nejakej knižnici s názvom foo (napríklad)
CPP
herec ekta kapoor
#include> #include> using> namespace> std;> > cout <<>' Something to display'>;> |
>
>
Všimnite si teraz, že je tu nejasnosť, na ktorú knižnicu cout poukazuje? Kompilátor to môže zistiť a neskompilovať program. V najhoršom prípade sa program môže skompilovať, ale zavolá nesprávnu funkciu, pretože sme nikdy nešpecifikovali, do ktorého menného priestoru identifikátor patrí.
Priestory názvov boli zavedené do C++ na riešenie konfliktov názvov identifikátorov. To zaistilo, že dva objekty môžu mať rovnaké meno a napriek tomu sa s nimi zaobchádza rozdielne, ak patria do rôznych menných priestorov. Všimnite si, ako sa v tomto príklade stal presný opak. Namiesto riešenia konfliktu mien v skutočnosti vytvárame konflikt mien.
Keď importujeme priestor názvov, v podstate sťahujeme všetky definície typov do aktuálneho rozsahu. Menný priestor std je obrovský. Má stovky preddefinovaných identifikátorov, takže je možné, že vývojár prehliadne skutočnosť, že v knižnici std existuje iná definícia ich zamýšľaného objektu. Bez toho, aby o tom vedeli, môžu pristúpiť k špecifikácii vlastnej implementácie a očakávať, že bude použitá v neskorších častiach programu. V aktuálnom priestore názvov by teda existovali dve definície rovnakého typu. Toto nie je povolené v C++ a aj keď sa program skompiluje, neexistuje spôsob, ako zistiť, ktorá definícia sa kde používa.
Riešením problému je explicitne špecifikovať, do ktorého menného priestoru patrí náš identifikátor pomocou operátora rozsahu (::). Jedným z možných riešení vyššie uvedeného príkladu teda môže byť
CPP
webový ovládač
#include> #include> > // Use cout of std library> std::cout <<>'Something to display'>;> > // Use cout of foo library> foo::cout <>'Something to display'>;> |
>
>
Ale treba písať std:: zakaždým, keď definujeme typ, je únavné. Náš kód tiež vyzerá chlpatejšie s množstvom definícií typov a sťažuje čítanie kódu. Zvážte napríklad kód na získanie aktuálneho času v programe
Príklad 2:
CPP
#include> #include> > auto> start = std::chrono::high_performance_clock::now()> > // Do Something> > auto> stop> >= std::chrono::high_peformance_clock::now();> auto> duration> >= std::duration_cast(stop - start);> |
>
>
Zdrojový kód, ktorý je posiaty komplikovanými a dlhými definíciami typov, nie je veľmi ľahko čitateľný. To je niečo, čomu sa vývojári snažia vyhnúť, pretože udržiavateľnosť kódu je pre nich dôležitá.
Existuje niekoľko spôsobov, ako vyriešiť túto dilemu, napr. špecifikovať presný menný priestor bez zahadzovania kódu pomocou štandardných kľúčových slov.
Zvážte použitie typových definícií
typedefs nás ušetria od písania dlhých definícií typov. V našom príklade 1 by sme mohli vyriešiť problém pomocou dvoch typov definícií, jedného pre knižnicu std a druhého pre foo
CPP
#include> #include> > typedef> std::cout cout_std;> typedef> foo::cout cout_foo;> > cout_std <<>'Something to write'>;> cout_foo <<>'Something to write'>;> |
>
>
Namiesto importovania celých menných priestorov importujte skrátený menný priestor
V príklade 2 sme mohli importovať iba chrono menný priestor pod std.
CPP
#include> #include> > // Import only the chrono namespace under std> using> std::chrono;> > auto> start = high_performance_clock::now();> > // Do Something> auto> stop = high_performance_clock::now();> auto> duration duration_cast(stop - start);> |
>
>
Príkaz môžeme použiť aj na import jedného identifikátora. Na import iba std::cout by sme mohli použiť
using std::cout;>
Ak stále importujete celé menné priestory, skúste to urobiť vo funkciách alebo v obmedzenom rozsahu a nie v globálnom rozsahu.
Použite príkaz std using namespace vo vnútri definícií funkcií alebo definícií tried, štruktúr. Pritom sa definície menného priestoru importujú do lokálneho rozsahu a aspoň vieme, kde môžu vzniknúť možné chyby, ak sa vyskytnú.
CPP
zásobník v ds
#include> > // Avoid this> using> namespace> std;> > void> foo()> {> >// Inside function> >// Use the import statement inside limited scope> >using> namespace> std;> > >// Proceed with function> }> |
>
>
Záver.
Diskutovali sme o alternatívnych metódach prístupu k identifikátoru z menného priestoru. Vo všetkých prípadoch sa vyhnite importovaniu celých menných priestorov do zdrojového kódu.
Aj keď osvojenie a vývoj osvedčených postupov kódovania môže nejaký čas trvať, vo všeobecnosti sa z dlhodobého hľadiska vyplácajú. Zámerom každého vývojára programovania by malo byť písanie čistého, jednoznačného a robustného kódu bez chýb.