Skip to content

Archives

  • 2022 január
  • 2021 december
  • 2021 november
  • 2021 október
  • 2021 szeptember

Categories

  • Nincs kategória
Trend RepositoryArticles and guides
Articles

GeeksforGeeks

On január 16, 2022 by admin

A namespace std használata általánosan rossz gyakorlatnak számít. Ennek a kijelentésnek az alternatívája az, hogy minden egyes típus deklarálásakor a hatókör-operátor(::) segítségével megadjuk azt a névteret, amelyhez az azonosító tartozik.
Az utasítás ugyan megkímél bennünket az std:: beírásától, amikor az std névtérben definiált osztályhoz vagy típushoz kívánunk hozzáférni, de az std névtér egészét importálja a program aktuális névterébe. Nézzünk néhány példát, hogy megértsük, miért nem biztos, hogy ez olyan jó dolog
Tegyük fel, hogy a cout-ot az std névtérből szeretnénk használni. Tehát azt írjuk

Példa 1:

CPP

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



Most a fejlődés későbbi szakaszában, a cout egy másik változatát szeretnénk használni, amelyet egy “foo” nevű könyvtárban (például)

CPP

#include <foo.h>
#include <iostream>
using namespace std;
cout << " Something to display";



Figyeljük meg, hogy van egy kétértelműség, Melyik könyvtárra mutat a cout? A fordító ezt észreveheti, és nem fordítja le a programot. A legrosszabb esetben a program mégis lefordítható, de rossz függvényt hív meg, mivel nem adtuk meg, hogy az azonosító melyik névtérbe tartozik.
A névtereket azért vezették be a C++-ban, hogy feloldják az azonosítónév-konfliktusokat. Ez biztosította, hogy két objektumnak lehet ugyanaz a neve, és mégis különbözőképpen kezelhetők, ha különböző névterekhez tartoznak. Vegyük észre, hogy ebben a példában pont az ellenkezője történt. Ahelyett, hogy feloldanánk egy névkonfliktust, valójában egy névkonfliktust hozunk létre.

Amikor importálunk egy névteret, lényegében az összes típusdefiníciót behúzzuk az aktuális hatókörbe. Az std névtér hatalmas. Több száz előre definiált azonosító van benne, így lehetséges, hogy egy fejlesztő figyelmen kívül hagyja, hogy a tervezett objektumának van egy másik definíciója is az std könyvtárban. Ennek nem tudatában a saját implementációjukat adhatják meg, és elvárhatják, hogy azt a program későbbi részeiben használják. Így ugyanannak a típusnak két definíciója létezne az aktuális névtérben. Ez a C++-ban nem megengedett, és még ha a program le is fordítja, nem lehet tudni, hogy melyik definíciót hol használják.

A probléma megoldása az, hogy a scope operátor (::) segítségével explicit módon megadjuk, hogy az azonosítónk melyik névtérbe tartozik. Így a fenti példa egyik lehetséges megoldása lehet

CPP

.

#include <foo>
#include <iostream>
std::cout << "Something to display";
foo::cout < "Something to display";



De mivel be kell írni std:: minden egyes alkalommal, amikor definiálunk egy típust, fárasztó. A kódunkat is szőrösebbé teszi a sok típusdefinícióval, és megnehezíti a kód olvasását. Vegyük például az aktuális idő lekérdezésének kódját a programban
Példa 2:

CPP

.

#include <chrono>
#include <iostream>
auto start = std::chrono::high_performance_clock::now()
auto stop
= std::chrono::high_peformance_clock::now();
auto duration
= std::duration_cast<std::chrono::milliseconds>(stop - start);



A bonyolult és hosszú típusdefiníciókkal telezsúfolt forráskód nem túl könnyen olvasható. Ezt a fejlesztők igyekeznek elkerülni, mivel a kód karbantarthatósága elsősorban fontos számukra.
Ez a dilemma megoldására van néhány módszer, azaz pontos névtér megadása anélkül, hogy a kódot std kulcsszavakkal szemetelnénk.

Gondoljunk a tipedefek használatára
A tipedefek megmentenek minket a hosszú típusdefiníciók írásától. A mi példánkban 1, megoldhatnánk a problémát két typedef használatával, egy az std könyvtárhoz és egy másik a foo

CPP
foo

hoz.

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



A teljes névterek importálása helyett, egy csonka névtér importálása
A 2. példában csak a chrono névteret importálhattuk volna az std alatt.

CPP

#include <chrono>
#include <iostream>
using std::chrono;
auto start = high_performance_clock::now();
auto stop = high_performance_clock::now();
auto duration duration_cast<milliseconds>(stop - start);



Az utasítást használhatjuk egyetlen azonosító importálására is. Ha csak az std::cout-ot szeretnénk importálni, akkor használhatjuk a

using std::cout;

Ha mégis egész névtereket importálunk, akkor próbáljuk ezt függvényeken belül vagy korlátozott hatókörben tenni, és ne globális hatókörben.
A “using namespace std” utasítást függvénydefiníciókban vagy osztály, strukt definíciókban használjuk. Ezzel a névtérdefiníciókat helyi hatókörbe importáljuk, és legalább tudjuk, honnan származhatnak az esetleges hibák, ha mégis felmerülnek.

CPP

#include <isotream>
using namespace std;
void foo()
{
using namespace std;
}



Következtetés.
A névtérből egy azonosító elérésének alternatív módszereit tárgyaltuk. Minden esetben kerüljük a teljes névterek importálását a forráskódba.
A jó kódolási gyakorlatok megtanulása és fejlesztése ugyan időbe telik, de hosszú távon általában kifizetődő. A tiszta, egyértelmű és robusztus, hibamentes kód írása minden programozó fejlesztő célja kell, hogy legyen.

Cikkcímkék :

C++

Gyakorlat Címkék :

Vélemény, hozzászólás? Kilépés a válaszból

Az e-mail-címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük

Archívum

  • 2022 január
  • 2021 december
  • 2021 november
  • 2021 október
  • 2021 szeptember

Meta

  • Bejelentkezés
  • Bejegyzések hírcsatorna
  • Hozzászólások hírcsatorna
  • WordPress Magyarország
  • DeutschDeutsch
  • NederlandsNederlands
  • SvenskaSvenska
  • DanskDansk
  • EspañolEspañol
  • FrançaisFrançais
  • PortuguêsPortuguês
  • ItalianoItaliano
  • RomânăRomână
  • PolskiPolski
  • ČeštinaČeština
  • MagyarMagyar
  • SuomiSuomi
  • 日本語日本語

Copyright Trend Repository 2022 | Theme by ThemeinProgress | Proudly powered by WordPress