Paziņojums izmantojot namespace std parasti tiek uzskatīta par sliktu praksi. Alternatīva šim paziņojumam ir norādīt nosaukumvietu, kurai pieder identifikators, izmantojot darbības jomas operatoru (::) katru reizi, kad deklarējam veidu.
Lai gan paziņojums mūs glābj no rakstīšanas std:: ikreiz, kad vēlamies piekļūt klasei vai tipam, kas definēts std nosaukumvietā, tas importē visu std nosaukumvietas pašreizējā programmas nosaukumvietā. Ņemsim dažus piemērus, lai saprastu, kāpēc tas varētu nebūt tik labi
Pieņemsim, ka vēlamies izmantot cout no std nosaukumvietas. Tātad mēs rakstām
1. piemērs:
CPP
#include> using> namespace> std;> > cout <<>' Something to Display'>;> |
>
>
Tagad vēlākā izstrādes posmā mēs vēlamies izmantot citu cout versiju, kas ir pielāgota, piemēram, kādā bibliotēkā ar nosaukumu foo.
CPP
#include> #include> using> namespace> std;> > cout <<>' Something to display'>;> |
>
>
Ņemiet vērā, ka tagad ir neskaidrības, uz kuru bibliotēku tas attiecas? Kompilators var to atklāt un nekompilēt programmu. Sliktākajā gadījumā programma joprojām var kompilēt, bet izsaukt nepareizo funkciju, jo mēs nekad neesam norādījuši, kurai nosaukumvietai pieder identifikators.
Vārdtelpas tika ieviestas C++, lai atrisinātu identifikatoru nosaukumu konfliktus. Tas nodrošināja, ka diviem objektiem var būt vienāds nosaukums, taču tie var tikt apstrādāti atšķirīgi, ja tie pieder pie dažādām nosaukumu telpām. Ievērojiet, kā šajā piemērā ir noticis tieši pretējais. Tā vietā, lai atrisinātu nosaukumu konfliktu, mēs faktiski izveidojam nosaukumu konfliktu.
Importējot nosaukumvietu, visas tipu definīcijas būtībā tiek iekļautas pašreizējā tvērumā. Std nosaukumvieta ir milzīga. Tam ir simtiem iepriekš definētu identifikatoru, tāpēc iespējams, ka izstrādātājs var aizmirst, ka standarta bibliotēkā ir cita paredzētā objekta definīcija. To neapzinoties, viņi var turpināt precizēt savu ieviešanu un sagaidīt, ka tā tiks izmantota vēlākās programmas daļās. Tādējādi pašreizējā nosaukumvietā vienam un tam pašam tipam būtu divas definīcijas. Tas nav atļauts C++, un pat tad, ja programma kompilē, nevar zināt, kura definīcija kur tiek izmantota.
Problēmas risinājums ir skaidri norādīt, kurai nosaukumvietai pieder mūsu identifikators, izmantojot darbības jomas operatoru (::). Tādējādi viens iespējamais risinājums iepriekšminētajam piemēram var būt
CPP
#include> #include> > // Use cout of std library> std::cout <<>'Something to display'>;> > // Use cout of foo library> foo::cout <>'Something to display'>;> |
>
>
Bet jāraksta std:: katru reizi, kad mēs definējam veidu, ir nogurdinoši. Tas arī padara mūsu kodu mataināku, izmantojot daudz veidu definīcijas, un apgrūtina koda nolasīšanu. Apsveriet, piemēram, kodu pašreizējā laika iegūšanai programmā
2. piemērs:
CPP
Linux rediģēt failu
#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);> |
>
>
Avota kodu, kas ir piesātināts ar sarežģītām un garām veidu definīcijām, nav ļoti viegli lasīt. No tā izstrādātāji cenšas izvairīties, jo koda uzturēšana viņiem ir ļoti svarīga.
Ir daži veidi, kā atrisināt šo dilemmu, t.i., norādiet precīzu nosaukumvietu, neizmantojot kodu ar std atslēgvārdiem.
Apsveriet iespēju izmantot typedefs
typedefs pasargā mūs no garu tipu definīciju rakstīšanas. Mūsu 1. piemērā mēs varētu atrisināt problēmu, izmantojot divus typedef vienu std bibliotēkai un otru foo
CPP
#include> #include> > typedef> std::cout cout_std;> typedef> foo::cout cout_foo;> > cout_std <<>'Something to write'>;> cout_foo <<>'Something to write'>;> |
>
>
Tā vietā, lai importētu visas nosaukumvietas, importējiet saīsinātu nosaukumvietu
2. piemērā mēs varējām importēt tikai chrono nosaukumvietu zem std.
CPP
npm notīrīt kešatmiņu
#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);> |
>
>
Mēs varam izmantot arī priekšrakstu viena identifikatora importēšanai. Lai importētu tikai std::cout, mēs varētu izmantot
using std::cout;>
Ja joprojām importējat visas nosaukumvietas, mēģiniet to darīt funkcijās vai ierobežotā tvērumā, nevis globālā tvērumā.
Izmantojiet use namespace std priekšrakstu funkciju definīcijās vai klases, struct definīcijās. To darot, nosaukumvietas definīcijas tiek importētas vietējā tvērumā, un mēs vismaz zinām, kur var rasties iespējamās kļūdas, ja tās rodas.
CPP
#include> > // Avoid this> using> namespace> std;> > void> foo()> {> >// Inside function> >// Use the import statement inside limited scope> >using> namespace> std;> > >// Proceed with function> }> |
>
>
Secinājums.
Mēs esam apsprieduši alternatīvas metodes, kā piekļūt identifikatoram no nosaukumvietas. Nekādā gadījumā izvairieties no visu nosaukumvietu importēšanas avota kodā.
Lai gan labas kodēšanas prakses apguve un attīstība var aizņemt kādu laiku, tā parasti atmaksājas ilgtermiņā. Jebkura programmēšanas izstrādātāja mērķis ir rakstīt tīru, nepārprotamu un stabilu, bez kļūdām kodu.