logo

Hvorfor bruk av navneområde std anses som dårlig praksis

Uttalelsen bruker navneområde std anses generelt som dårlig praksis. Alternativet til denne setningen er å spesifisere navneområdet som identifikatoren tilhører ved å bruke scope-operatoren(::) hver gang vi erklærer en type.
Selv om uttalelsen sparer oss fra å skrive std:: når vi ønsker å få tilgang til en klasse eller type definert i std-navneområdet, importerer den hele std navneområde inn i programmets gjeldende navneområde. La oss ta noen eksempler for å forstå hvorfor dette kanskje ikke er så bra
La oss si at vi ønsker å bruke cout fra std navneområdet. Så vi skriver

Eksempel 1:



CPP








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

>

>

Nå på et senere utviklingsstadium ønsker vi å bruke en annen versjon av cout som er tilpasset implementert i et bibliotek kalt foo (for eksempel)

sara ali khan alder

CPP




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

>

>

Legg merke til at det nå er en tvetydighet, hvilket bibliotek peker cout på? Det kan hende kompilatoren oppdager dette og ikke kompilerer programmet. I verste fall kan programmet fortsatt kompilere, men kalle feil funksjon, siden vi aldri spesifiserte hvilket navneområde identifikatoren tilhørte.
Navneområder ble introdusert i C++ for å løse identifikatornavnkonflikter. Dette sikret at to objekter kan ha samme navn og likevel behandles forskjellig hvis de tilhørte forskjellige navneområder. Legg merke til hvordan det motsatte har skjedd i dette eksemplet. I stedet for å løse en navnekonflikt, skaper vi faktisk en navnekonflikt.

Når vi importerer et navneområde, trekker vi i hovedsak alle typedefinisjoner inn i gjeldende omfang. Std-navneområdet er enormt. Den har hundrevis av forhåndsdefinerte identifikatorer, så det er mulig at en utvikler kan overse det faktum at det er en annen definisjon av deres tiltenkte objekt i std-biblioteket. Uvitende om dette kan de gå videre med å spesifisere sin egen implementering og forvente at den blir brukt i senere deler av programmet. Dermed vil det eksistere to definisjoner for samme type i gjeldende navneområde. Dette er ikke tillatt i C++, og selv om programmet kompilerer er det ingen måte å vite hvilken definisjon som brukes hvor.

Løsningen på problemet er å eksplisitt spesifisere hvilket navneområde vår identifikator tilhører ved å bruke scope-operatoren (::). Dermed kan en mulig løsning på eksemplet ovenfor være

CPP

størrelsen på python




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

>

>

Men må skrive std:: hver gang vi definerer en type er kjedelig. Det gjør også at koden vår ser håretere ut med mange typedefinisjoner og gjør det vanskelig å lese koden. Tenk for eksempel på koden for å få gjeldende tid i programmet
Eksempel 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);>

>

>

Kildekoden som er full av kompliserte og lange typedefinisjoner er ikke veldig lett å lese. Dette er noe utviklere prøver å unngå siden vedlikehold av kode er viktigst for dem.
Det er noen få måter å løse dette dilemmaet på, dvs. spesifisere eksakt navneområde uten forsøpling av kode med standard nøkkelord.

Vurder å bruke typedefs
typedefs redder oss fra å skrive lange typedefinisjoner. I vårt eksempel 1 kunne vi løse problemet ved å bruke to typedefs en for std-bibliotek og en annen for foo

CPP




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

>

>

I stedet for å importere hele navneområder, importer et avkortet navneområde
I eksempel 2 kunne vi bare ha importert chrono-navneområdet under std.

CPP

streng til int-konverter




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

>

>

Vi kan også bruke setningen for å importere en enkelt identifikator. For kun å importere std::cout kunne vi bruke

using std::cout;>

Hvis du fortsatt importerer hele navneområder, prøv å gjøre det innenfor funksjoner eller begrenset omfang og ikke i globalt omfang.
Bruk use namespace std-setningen i funksjonsdefinisjoner eller klasse, struct-definisjoner. Ved å gjøre det blir navneområdedefinisjonene importert til et lokalt omfang, og vi vet i det minste hvor mulige feil kan oppstå hvis de oppstår.

CPP




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

>

tiger løve forskjell

>

Konklusjon.
Vi har diskutert alternative metoder for å få tilgang til en identifikator fra et navneområde. Unngå i alle tilfeller å importere hele navneområder til kildekoden.
Selv om god kodingspraksis kan ta litt tid å lære og utvikle, betaler de seg vanligvis i det lange løp. Å skrive ren, entydig og robust feilfri kode bør være intensjonen til enhver programmeringsutvikler.