logo

Hvorfor brug af navneområde std betragtes som dårlig praksis

Udtalelsen bruger navneområde std anses generelt for dårlig praksis. Alternativet til denne sætning er at angive det navneområde, som identifikatoren tilhører, ved at bruge scope-operatoren(::) hver gang vi erklærer en type.
Selvom udsagnet redder os fra at skrive std:: når vi ønsker at få adgang til en klasse eller type defineret i std-navneområdet, importerer den hele std navneområde ind i programmets aktuelle navneområde. Lad os tage et par eksempler for at forstå, hvorfor det måske ikke er så godt
Lad os sige, at vi ønsker at bruge cout fra std-navneområdet. Så vi skriver

Eksempel 1:



CPP








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

>

>

Nu på et senere udviklingstrin ønsker vi at bruge en anden version af cout, der er tilpasset implementeret i et bibliotek kaldet foo (for eksempel)

sara ali khan alder

CPP




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

>

>

Bemærk nu, at der er en tvetydighed, hvilket bibliotek peger cout på? Compileren kan opdage dette og ikke kompilere programmet. I værste fald kan programmet stadig kompilere, men kalder den forkerte funktion, da vi aldrig har specificeret hvilket navneområde identifikatoren tilhørte.
Navneområder blev indført i C++ for at løse identifikatornavnekonflikter. Dette sikrede, at to objekter kan have samme navn og alligevel behandles forskelligt, hvis de tilhørte forskellige navneområder. Læg mærke til, hvordan det stik modsatte er sket i dette eksempel. I stedet for at løse en navnekonflikt, skaber vi faktisk en navnekonflikt.

Når vi importerer et navneområde, trækker vi i det væsentlige alle typedefinitioner ind i det aktuelle omfang. Std-navnerummet er enormt. Det har hundredvis af foruddefinerede identifikatorer, så det er muligt, at en udvikler kan overse det faktum, at der er en anden definition af deres tilsigtede objekt i std-biblioteket. Uvidende om dette kan de fortsætte med at specificere deres egen implementering og forvente, at den bliver brugt i senere dele af programmet. Der ville således eksistere to definitioner for den samme type i det nuværende navneområde. Dette er ikke tilladt i C++, og selvom programmet kompilerer, er der ingen måde at vide, hvilken definition der bruges hvor.

Løsningen på problemet er eksplicit at angive, hvilket navneområde vores identifikator tilhører ved hjælp af scope-operatoren (::). En mulig løsning på ovenstående eksempel kan således være

CPP

js multiline streng




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

>

>

Men skal skrive std:: hver gang vi definerer en type er kedelig. Det får også vores kode til at se mere behårede ud med masser af typedefinitioner og gør det svært at læse koden. Overvej for eksempel koden for at få det aktuelle tidspunkt 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, der er fyldt med komplicerede og lange typedefinitioner, er ikke særlig let at læse. Dette er noget, udviklere søger at undgå, da kodevedligeholdelse hovedsageligt er vigtigt for dem.
Der er et par måder at løse dette dilemma på, dvs. at angive nøjagtigt navneområde uden at strø kode med standardnøgleord.

Overvej at bruge typedefs
typedefs redder os fra at skrive lange typedefinitioner. I vores eksempel 1 kunne vi løse problemet ved at bruge to typedefs, en for std-bibliotek og en anden 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 at importere hele navnerum skal du importere et afkortet navneområde
I eksempel 2 kunne vi kun have importeret chrono-navneområdet under std.

CPP

hvis andet hvis andet java




#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å bruge sætningen til at importere en enkelt identifikator. For kun at importere std::cout kunne vi bruge

using std::cout;>

Hvis du stadig importerer hele navneområder, så prøv at gøre det inden for funktioner eller begrænset omfang og ikke i globalt omfang.
Brug brug af navneområde std-sætning inde i funktionsdefinitioner eller klasse, struct-definitioner. Ved at gøre det bliver navneområdedefinitionerne importeret til et lokalt omfang, og vi ved i det mindste, hvor mulige fejl kan opstå, hvis de opstå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> }>

>

boolesk til streng java

>

Konklusion.
Vi har diskuteret alternative metoder til at få adgang til en identifikator fra et navneområde. Undgå i alle tilfælde at importere hele navneområder til kildekoden.
Selvom god kodningspraksis kan tage lidt tid at lære og udvikle, betaler de sig generelt i det lange løb. At skrive ren, utvetydig og robust fejlfri kode bør være hensigten med enhver programmeringsudvikler.