logo

Kodėl vardų erdvės std naudojimas laikomas bloga praktika

Pareiškimas naudojant vardų sritį std paprastai laikoma bloga praktika. Šio teiginio alternatyva yra nurodyti vardų erdvę, kuriai priklauso identifikatorius, naudojant srities operatorių (::) kiekvieną kartą, kai deklaruojame tipą.
Nors teiginys gelbsti mus nuo spausdinimo std:: kai norime pasiekti klasę ar tipą, apibrėžtą std vardų erdvėje, ji importuoja visą std vardų erdvę į dabartinę programos vardų erdvę. Paimkime keletą pavyzdžių, kad suprastume, kodėl tai gali būti ne toks geras dalykas
Tarkime, kad norime naudoti cout iš std vardų erdvės. Taigi rašome

1 pavyzdys:



CPP








#include> using> namespace> std;> > cout <<>' Something to Display'>;>

>

>

Dabar vėlesniame kūrimo etape norime naudoti kitą cout versiją, kuri pagal užsakymą įdiegta tam tikroje bibliotekoje, vadinamoje foo (pavyzdžiui)

CPP




#include> #include> using> namespace> std;> > cout <<>' Something to display'>;>

>

>

Atkreipkite dėmesį, kad dabar yra neaiškumų, į kurią biblioteką reikia atkreipti dėmesį? Kompiliatorius gali tai aptikti ir nesukompiliuoti programos. Blogiausiu atveju programa vis tiek gali kompiliuoti, bet iškviesti netinkamą funkciją, nes niekada nenurodėme, kuriai vardų erdvei priklauso identifikatorius.
Vardų erdvės buvo įvestos į C++, kad būtų išspręstos identifikatorių vardų konfliktai. Tai užtikrino, kad du objektai gali turėti tą patį pavadinimą ir vis dėlto būti traktuojami skirtingai, jei priklausytų skirtingoms vardų erdvėms. Atkreipkite dėmesį, kaip šiame pavyzdyje atsitiko visiškai priešingai. Užuot išsprendę vardų konfliktą, iš tikrųjų sukuriame vardų konfliktą.

kaip skaityti csv failą java

Kai importuojame vardų erdvę, mes iš esmės įtraukiame visus tipų apibrėžimus į dabartinę sritį. Std vardų erdvė yra didžiulė. Jame yra šimtai iš anksto nustatytų identifikatorių, todėl gali būti, kad kūrėjas gali nepastebėti, kad std bibliotekoje yra kitas numatyto objekto apibrėžimas. To nežinodami, jie gali nurodyti savo įgyvendinimą ir tikėtis, kad jis bus naudojamas vėlesnėse programos dalyse. Taigi dabartinėje vardų erdvėje būtų du to paties tipo apibrėžimai. Tai neleidžiama C++ ir net jei programa kompiliuoja, nėra jokio būdo žinoti, kuris apibrėžimas kur naudojamas.

Problemos sprendimas yra aiškiai nurodyti, kuriai vardų erdvei priklauso mūsų identifikatorius, naudojant srities operatorių (::). Taigi vienas iš galimų aukščiau pateikto pavyzdžio sprendimų gali būti

CPP




#include> #include> > // Use cout of std library> std::cout <<>'Something to display'>;> > // Use cout of foo library> foo::cout <>'Something to display'>;>

>

>

Bet reikia rašyti std:: kiekvieną kartą, kai apibrėžiame tipą, yra nuobodu. Taip pat mūsų kodas atrodo plaukuotesnis, nes yra daug tipo apibrėžimų, ir apsunkina kodo skaitymą. Apsvarstykite, pavyzdžiui, kodą, kaip gauti dabartinį laiką programoje
2 pavyzdys:

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);>

>

>

Sudėtingais ir ilgais tipo apibrėžimais nusėtas šaltinio kodas nėra labai lengvas skaityti. To kūrėjai siekia išvengti, nes jiems svarbiausia yra kodo priežiūra.
Yra keletas būdų, kaip išspręsti šią dilemą, t. y. nurodykite tikslią vardų erdvę be kodo su std raktiniais žodžiais.

Apsvarstykite galimybę naudoti typedef
typedefs apsaugo mus nuo ilgų tipo apibrėžimų. 1 pavyzdyje problemą galėtume išspręsti naudodami du tipodef, vieną std bibliotekai ir kitą foo

CPP




#include> #include> > typedef> std::cout cout_std;> typedef> foo::cout cout_foo;> > cout_std <<>'Something to write'>;> cout_foo <<>'Something to write'>;>

>

>

Užuot importavę visas vardų sritis, importuokite sutrumpintą vardų erdvę
2 pavyzdyje galėjome importuoti tik chrono vardų erdvę pagal 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);>

>

>

Taip pat galime naudoti teiginį importuodami vieną identifikatorių. Norėdami importuoti tik std::cout, galime naudoti

using std::cout;>

Jei vis tiek importuojate visas vardų sritis, pabandykite tai padaryti funkcijose arba ribotoje srityje, o ne visuotinėje srityje.
Naudokite vardų erdvės std teiginį funkcijų apibrėžimuose arba klasėje, struktūrų apibrėžimuose. Tai darant vardų erdvės apibrėžimai importuojami į vietinę sritį, ir mes bent jau žinome, kur gali kilti galimų klaidų, jei jos atsiranda.

CPP




#include> > // Avoid this> using> namespace> std;> > void> foo()> {> >// Inside function> >// Use the import statement inside limited scope> >using> namespace> std;> > >// Proceed with function> }>

>

>

Išvada.
Aptarėme alternatyvius metodus, kaip pasiekti identifikatorių iš vardų erdvės. Visais atvejais venkite importuoti visas vardų sritis į šaltinio kodą.
Nors geros kodavimo praktikos išmokti ir tobulėti gali prireikti šiek tiek laiko, ji paprastai pasiteisina ilgainiui. Bet kurio programavimo kūrėjo tikslas turėtų būti švaraus, nedviprasmiško ir patikimo kodo rašymas be klaidų.