Niyə "std ad boşluğu istifadə" pis praktik hesab?

using namespace std yazı kodunun yanlış olduğunu və yerinə std::coutstd::cin istifadə etməyim lazım olduğunu std::cout .

Niyə using namespace std pis praktikanı hesab edir? Səmərəsizdirmi və ya qeyri-müəyyən dəyişənləri ( std funksiya kimi eyni adlı dəyişənləri) elan edə bilərmi? Performansı təsir edirmi?

2212
21 сент. akbiggs tərəfindən müəyyən Sep 21 2009-09-21 06:08 '09 at 6:08 am 2009-09-21 06:08
@ 36 cavab
  • 1
  • 2

Bu, performansla bağlı deyil. Ancaq bunu düşünün: Foo və Bar adlı iki kitabxanadan istifadə edirsiniz:

 using namespace foo; using namespace bar; 

Hər şey yaxşı işləyir, heç bir problem olmadan Quux() Foo və Quux() dan Blah() Quux() . Amma bir gün, Quux() adlı bir xüsusiyyət təklif edən Foo 2.0-a yeni bir versiyaya Quux() . İndi bir münaqişə var: həm də Foo 2.0 və Bar idxal Quux() sizin qlobal ad boşluğunuzdadır. Bu, xüsusilə funksiyanın parametrləri uyğun olduqda, düzəltmək üçün bir az səy tələb edəcək.

foo::Blah()bar::Quux() , foo::Quux() tətbiqi qeyri-hadisə ola bilər.

1863
21 сент. Greg Hewgill tərəfindən verilmiş cavab Sep 21 2009-09-21 06:13 '09 at 6:13 'da 2009-09-21 06:13

Greg yazırdı hər şey ilə razıyam, amma əlavə etmək istərdim: Greg dedi ki, hətta pis ola bilər!

Foo 2.0 kütüphanesi Quux() funksiyasını təqdim edə bilər ki, bu da Quux() çağırışlarınızın bəzi Quux() bar::Quux() dan daha yaxşı bir Quux() . Sonra kodunuzu tərtib edir , lakin səssizcə yanlış funksiyanı çağırır və tanrı nə bilir. Bu hər şey ola biləcəyi qədər pisdir.

std bir çoxu digər std çox görünən çoxsaylı identifikatorlar (düşüncə list , sort , string , iterator və s.) Ehtiva etdiyini unutmayın.

Bunun mümkün olmadığını düşünsəniz: necə baş verdiyini təsvir edən bir sual var idi ( std:: prefiksini itirdiyinə görə yanlış funksiya). Mən bu cavabı verdikdən təxminən yarım il sonra. Belə bir sualın daha yeni nümunəsi. Beləliklə, bu, əsl problemdir.


border=0

Burada başqa bir məlumat mənbəyi var: bir neçə il bundan əvvəl da standart std:: kitabxanadan hər kəs üçün prefiks ehtiyacını sarsıtdığını düşünməyə std:: . Sonra başlanğıcda funksiya sahələri istisna olmaqla, direktivlər və bəyannamələrin using qadağan olunduğu bir layihədə çalışdım. Nəyə görə? Çoxumuz prefiks yazmaq üçün istifadə etmək üçün bir neçə həftə keçirdik və bir neçə həftədən sonra, əksəriyyətimiz kodun həqiqətən daha oxunaqlı olduğuna razılaşdılar. Bunun bir səbəbi var: Əgər daha qısa və ya uzun nəsr istəsəniz, bu subyektivdir, amma ön kodlar obyektiv olaraq kodu aydınlaşdırır. Yalnız tərtibçi deyil, ancaq hansı identifikatorun qeyd olunduğunu görmək daha asandır.

On il ərzində bu layihə bir neçə milyon xəttin kodlarına qədər artıb. Bu müzakirələr təkrar-təkrar qaldıqdan sonra layihədə istifadə olunan funksiyanı necə istifadə etdiyini bir dəfə maraqlandırdım. Mən bunun üçün mənbələr tapdım və istifadə edildiyi yerdən yalnız bir və ya iki düzəldən yer tapdım. Mənim üçün bu, bir dəfə cəhd edildikdə, inkişaf etməkdə olanlar heç bir std:: ağrıya məruz qalmır, hətta istifadə edilsə belə, hər bir 100 kLO hətta bir dəfə direktivləri istifadə etmək üçün kifayətdir.


border=0

Aşağı xətt: açıq-aşkar prefiks hər şeyə zərər vermir, çox az istifadə olunur və obyektiv üstünlüklərə malikdir. Xüsusilə kodun şərhini kompilyator və insan oxucuları tərəfindən asanlaşdırır - kodu yazarkən bu, əsasən, əsas məqam olmalıdır.

1214
21 сент. cavab sbi verildi 21 Sep 2009-09-21 12:26 '09 da 12:26 'də 2009-09-21 12:26

using namespace başlıq fayllarında using namespace problemi, bu digər ad boşluqlarını "istifadə" (yəni, hər şeyə baxın) üçün siniflərinizi (üstbilgi faylları daxil olmaqla) istifadə etmək istəyən hər kəsə məcbur edir.

Bununla belə, istifadə etdiyiniz ifadəni (xüsusi) * .cpp fayllarından sərbəst istifadə edə bilərsiniz.


Bəzi insanlar mənim "özgür" ifadəyimlə razı olmadığını unutmayın - çünki cpp ifadəsini istifadə başlıqdan daha yaxşıdır (başlıq faylını daxil edən insanları təsir etmir) bu hələ də yaxşı deyildir (çünki kodun tərkibinə görə, bu, sinifin tətbiqini çətinləşdirə bilər). Tez-tez soruşulan suallar mövzusu deyir

İstifadə qaydası köhnəlmiş C ++ kodları üçün və ad boşluğuna keçid asanlaşdırmaq üçün mövcuddur, lakin ən azı yeni C ++ kodunda müntəzəm olaraq istifadə etməməlisiniz.

Sual iki alternativ təklif edir:

  • İstifadə qaydası:

     using std::cout; // a using-declaration lets you use cout without qualification cout << "Values:"; 
  • Yalnız std yazın ::

     std::cout << "Values:"; 
337
21 сент. ChrisW Sep 21 tərəfindən verilmiş cavab 2009-09-21 06:22 '09 saat 06:22 'da 2009-09-21 06:22

Mən son zamanlarda Visual Studio 2010 haqqında şikayət etdilər . Demək olar ki, bütün mənbə fayllarının iki xətti var:

 using namespace std; using namespace boost; 

Çox Boost funksiyaları C + + 0x standartına daxil edilir və Visual Studio 2010 C ++ 0x bir çox var, buna görə də bu proqramlar tərtib edilmədi.

Buna görə, using namespace X; Bu gələcək çekin bir formasıdır, kitabxanalarda istifadə edilən dəyişikliklərin və / və ya başlıqlı faylların proqramın pozulmamasını təmin edən bir üsuldur.

213
28 окт. Cavab David Thornley 28 oktyabr 2010-10-28 20:37 '10 at 20:37 2010-10-28 20:37

Qısa versiya: başlıq fayllarında bəyannamələrin və direktivlərin qlobal istifadəsindən istifadə etməyin. Proqram fayllarında onları istifadə etməkdən çəkinməyin. Burada, Herb Sutter və Andrey Aleksandrescu bu məsələ ilə əlaqədar C ++ Kodlama Standartlarında (mənim diqqətimi cəsarətli) söyləmək məcburiyyətindədir:

Xülasə

Namizət adları başqaları üçün deyil, rahatlığı üçündir: bir istifadəçi bəyannaməsini yazmayın və ya #include direktivindən əvvəl direktiv istifadə edin.

Nəticə: direktivlər və ya bəyannamələr istifadə edərək başlıq fayllarında ad boşluğunun səviyyəsini yazmayın; əvəzində ad boşdur - bütün adları təsvir edir. (İkinci qayda birincidən qaynaqlanır, çünki başlıqlar heç bir şey bilməyəcəkdir, başqa bir mövzu başlıqları onların arxasında görünə bilər.)

Talk

Qısacası: adın boşluğunu tətbiq edəcəyi fayllarda bəyanatları və direktivləri istifadə edə və istifadə etməlisiniz. Əksinə təkrarlanan iddialara baxmayaraq, bəyanatlar və direktivlər istifadə edən ad boşluq deyil və onlar ad boşluğunun məqsədini həyata keçirmirlər. Əksinə, bu ad boşluqlarını istifadə etməyə imkan verir .

178
03 нояб. mattnewport tərəfindən verilmiş cavab 03 Noyabr. 2014-11-03 23:00 '14 saat 23:00 'də 2014-11-03 23:00

Xüsusən başlıqlarda qlobal miqyasda bir direktivdən istifadə edə bilməzsiniz. Bununla belə, başlıq faylında belə tətbiq olunduğu hallar var:

 template <typename FloatType> inline FloatType compute_something(FloatType x) { using namespace std; //no problem since scope is limited return exp(x) * (sin(x) - cos(x * 2) + sin(x * 3) - cos(x * 4)); } 

Bu, daha qısadır və istifadəçi müəyyən edilmiş üzmə nöqtəsi növləri ilə işləmək bacarığına malik olduğundan ( std::sin , std::cos ...) daha yaxşıdır (arqumentə bağlı axtarış vasitəsi ilə).

110
21 сент. Cavab verilir robson3.14 21 sep . 2009-09-21 18:47 '09 da 18:47 'də, 2009-09-21 18:47

Qlobal istifadə etməyin.

Qlobal olaraq istifadə edildikdə yalnız "pis" sayılır. Çünki:

  • Proqramlaşdırma etdiyiniz adları yığışdırırsınız.
  • Oxucular, using namespace xyz çox using namespace xyz etdiyiniz zaman müəyyən bir identifikatorun using namespace xyz .
  • Kaynak kodunuzun digər okuyucuları üçün nə olursa olsun, bu, ən çox oxucu üçün daha doğrudur: özünüz. Bir il və ya iki dəfə geri qayıdın ...
  • using namespace std , using namespace std bütün materiallar haqqında məlumatınız olmaya bilər və başqa #include əlavə edildikdə və ya yeni bir C ++ versiyasına keçdiyinizdə, siz bilmədiyiniz adı çatışmazlıqları əldə edə bilərsiniz.

Yerli olaraq istifadə edə bilərsiniz.

Davam edin və yerli olaraq (demək olar ki, sərbəst) istifadə edin. Bu, əlbəttə, std:: təkrarlanmasına mane olur və təkrarlama da pisdir.

Yerli istifadə üçün İdiom

C ++ 03-də, dərsləriniz üçün swap funksiyasını həyata keçirmək üçün bir deyim-şablon kodu var idi. Siz, həqiqətən, using namespace std yerli using namespace std - və ya ən azı using std::swap :

 class Thing { int value_; Child child_; public: // ... friend void swap(Thing  Thing  }; void swap(Thing  Thing  { using namespace std; // make `std::swap` available // swap all members swap(a.value_, b.value_); // `std::stwap(int, int)` swap(a.child_, b.child_); // `swap(Child or `std::swap(...)` } 

Bu aşağıdakı sehrdir:

  • Derleyici, value_ üçün std::swap value_ , yəni. void std::swap(int, int) .
  • Bir void swap(Child Child> overload void swap(Child Child> , kompilyator onu seçəcək.
  • Bu yüklənmə olmazsa kompilyator void std::swap(Child> və onları yaxşı əvəz etməyə çalışacaqdır.

C ++ 11 bu şablonu artıq istifadə etmək üçün bir səbəb deyil. std::swap tətbiqi potensial yüklənmə tapmaq və onu seçmək üçün dəyişdirilmişdir.

86
18 янв. Cavab 18 yanvar tarixində verilir 2013-01-18 12:34 '13 at 12:34 2013-01-18 12:34

Doğru üstbilgi faylları içe hex , bir anda hex , left , plus və ya count ölçekte hex adlar var. std:: bu adları ehtiva etdiyini bilmirsinizsə, bu təəccüblü ola bilər. Yerli olaraq bu adları istifadə etməyə çalışarsanız, bu bəzi qarışıqlıqlara səbəb ola bilər.

Bütün standart elementlər öz ad boşluğunda olduqda, kodunuz və ya digər kitabxanalarla ad ziddiyyətləri barədə narahat olmayın.

73
21 сент. Cavab sth 21 sep verilir . 2009-09-21 06:23 '09 saat 06:23 'da 2009-09-21 06:23

Təcrübəli proqramçılar problemlərini həll edən hər şeyi istifadə edirlər və ortaya çıxan yeni problemlərdən çəkinirlər və bu dəqiq səbəbdən başlıq səviyyəsində göstərici direktivlərindən istifadə etməmişlər.

Təcrübəli proqramçılar da mənbələr faylları daxilində adları tamamilə seçməməyi qarşısını almaq üçün çalışırlar. Bunun üçün kiçik bir səbəb, heç bir cəlbedici səbəb olmadıqda, kifayət qədər kod olmadıqda, daha çox kod yazmaq zərif deyil. Bunun əsas səbəbi axtarışın bağımlı arqumentinin (ADL) əlil olmasıdır.

Bu yaxşı səbəblər hansılardır? Bəzən proqramçılar açıq-aydın ADL-ni istəmirlər, digər hallarda isə qeyri-müəyyənliyi aradan qaldırmaq istəyirlər.

Beləliklə, hər şey düzəldilir:

  • Funksiyaların səviyyəsində direktivlərdən istifadə və funksiyaların həyata keçirilməsi zamanı bəyannamələrin istifadəsi
  • Kaynak fayllarda mənbə-səviyyəli bildirişləri istifadə edin
  • (Bəzən) mənbə faylının səviyyəsində istifadə
39
29 марта '11 в 11:10 2011-03-29 11:10 Cavab Aleksandr Poluektovun 29 mart '11' də saat 11:10 'də verdiyi 2011-03-29 11:10

Başqa bir səbəb isə sürprizdir.

Əgər mən std::cout << blah yerinə cout << blah görürsən

Hesab edirəm ki, bu cout nədir? Normal bir cout mu? Bu xüsusi bir şey mi?

37
21 сент. Martin Beckett tərəfindən verilmiş cavab 21 sentyabr. 2009-09-21 06:13 '09 at 6:13 'da 2009-09-21 06:13

Qəbul edirəm ki, bu, dünyada istifadə edilə bilməz, amma bu qədər pis deyil, namespace kimi istifadə etmək. Burada "C ++ Proqramlaşdırma dili" nin nümunəsi:

 namespace My_lib { using namespace His_lib; // everything from His_lib using namespace Her_lib; // everything from Her_lib using His_lib::String; // resolve potential clash in favor of His_lib using Her_lib::Vector; // resolve potential clash in favor of Her_lib } 

Bu nümunədə biz potensial adı çarpışmalarını və onların tərkibinə aid qeyri-müəyyənlikləri həll etdik.

Burada açıq şəkildə elan edilmiş adlar ( His_lib::String kimi bəyanatları istifadə edərək elan edilmiş adlar daxil olmaqla) istifadə olunan direktivdən ( using namespace Her_lib ) başqa bir sahədə mövcud olan using namespace Her_lib .

36
29 авг. Cavab Oleksiy 29 avqust verilir . 2013-08-29 12:44 '13 at 12:44 2013-08-29 12:44

Mən də bu pis bir təcrübə hesab edirəm. Niyə? Yalnız bir dəfə ad boşluğunun funksiyasını materialımı bölüşdürmək olduğunu düşünürdüm ki, hər şeyi bir qlobal çantaya ataraq onu korlamayacağam. Lakin, tez-tez "cout" və "cin" using std::cout; using std::cin; edərəm, yazıram: using std::cout; using std::cin; using std::cout; using std::cin; cpp faylında (başlıq faylında heç vaxt, #include istifadə edərək paylanmışdır). Mən heç kim cout bir cout ya da cin deyən heç bir şey düşünməyəcək;)

26
21 сент. Cavab Yelonek 21 sep verilir . 2009-09-21 12:34 '09 at 12:34 2009-09-21 12:34

Kodu görmək və nə etdiyini bilmək gözəldir. std::cout görürsənsə, mən std kitabxanasının cout axını olduğunu bilirəm. Bir cout gördükdə, mən bilmirəm. Bu std kitabxanasından cout axını ola bilər. Və ya bəlkə int cout = 0; eyni funksiyadan 10 xətt yüksəkdir. Və ya bu faylda cout adlı static dəyişən. Hər şey ola bilər.

İndi bir milyon xətt kodunu xüsusilə böyük olmayan bir xətt çəkin və bir səhv axtarırsınız, yəni bu xəttdə bir xətt olduğunu bilirsiniz ki, bunun nə ediləcəyini etmirsiniz. cout << 1; static int adlı cout adlı bir oxuya bilərsiniz, bir bit buraxıb nəticə çıxarın. Bir səhv axtarırsınızsa, onu yoxlamaq məcburiyyətindəyəm. std::cout görməyi həqiqətən std::cout necə görürsən?

Bu müəllimlərdən biri olmağınızdan asılı olmayaraq, həqiqətən yaxşı bir fikir kimi görünən və yaşamaq üçün hər hansı bir kod yazmaq və saxlamağa ehtiyac olmadığı şeylərdən biridir. Kodunu görməyi sevirəm (1) nə etdiyini bilirəm; və (2) əminəm ki, bu yazan şəxs nə etdiyini bilirdi.

21
13 марта '14 в 20:22 2014-03-13 20:22 Cavab verilir gnasher729 13 mart 13:22 'də 20:22 2014-03-13 20:22

Mürəkkəbliyi idarə edən hər şey. Bir ad sahəsi istifadə etməyiniz istəməyən bir şeyə gətirib çıxaracaq və buna görə də səhv etmək çətin ola bilər (bəlkə də deyirəm). Std :: hər yerdə oxumaq daha çətindir (daha çox mətn və bütün bunlar).

Kurslar üçün atlar - mürəkkəbliyi idarə edə bilərsiniz və hiss edə bilərsiniz.

20
21 сент. cavab Preet Sangha 21 sep verilir . 2009-09-21 06:14 '09 at 6:14 pm 2009-09-21 06:14

Eyni zamanda bir çox isim alanını istifadə edərək fəlakət üçün bir resept kimi görünür, amma JUST ad sahəsi std istifadə edərək, yalnız mənim fikrimcə std ad sahəsi böyük bir şey deyil, çünki redefinasiya yalnız öz kodunuzla baş verə bilər. .

Beləliklə, onları "int" və ya "sinif" kimi qorunub adlar hesab edin və bütün bunlar.

İnsanlar bu qədər anal olmamalıdır. Müəlliminiz hər zaman haqlıydı. Yalnız bir ədədi istifadə edin; bu, ilk növbədə ad boşluqlarını istifadə edən bütün nöqtəsidir. Bir dəfədən çox istifadə etməməlisiniz. Əgər bu sizin deyilsə. Beləliklə yenidən tərif vermir.

17
09 нояб. Cavab verən istifadəçi2645752 09 Noyabr. 2013-11-09 18:09 '13 at 18:09 2013-11-09 18:09
  • Siz stil və ən yaxşı təcrübə haqqında fərqli düşüncələriniz olan insanlar tərəfindən yazılmış kodu oxuya bilərsiniz.

  • Cout istifadə əgər, heç kim utandım. Amma uçan bir çox ad varsa, bu sinifi görürsən və nə etdiyinə tam əmin deyilik, çünki açıq ad bir növ şərh edir. Bir baxışda görə bilərsiniz: "Oh, bu bir fayl sistemi əməliyyatı" və ya "Nə şəbəkə işi edir."

17
21 сент. Cavab Dustin Getz 21 sep tərəfindən verilir . 2009-09-21 07:04 '09 at 07:04 'da 2009-09-21 07:04

Hesab edirəm

 // myHeader.h #include <sstream> using namespace std; // someoneElses.cpp/h #include "myHeader.h" class stringstream { // uh oh }; 

Xahiş edirik, bu, sadə bir nümunədir. 20-dən çox fayl və digər idxal fayllarınız varsa, problemi həll etmək üçün bir çox asılılıq olacaq. Bütün bunlardan ən pisdir, münaqişə ilə bağlı olan təriflərə görə digər modullarda əlaqəli olmayan səhvlər əldə edə bilərsiniz.

Bu qorxunc deyil, başlıq fayllarında və ya qlobal ad boşluğunda istifadə etmədən baş ağrısından qurtulacaqsınız. Çox güman ki, bu çox məhdud ərazilərdə edilə bilər, amma mənim funksiyalarımın harada olduğunu öyrənmək üçün əlavə beş simvol daxil olmamışam.

16
21 сент. Cavab Ron Warholic 21 sep tərəfindən verilir . 2009-09-21 06:19 '09 at 06:19 AM 2009-09-21 06:19

Problemi aydınlaşdırmaq üçün xüsusi bir nümunə. Təsəvvür edin ki, hər biriniz öz adınız olan 2 kitabxana, foo və barınız var:

 namespace foo { void a(float) {  } } namespace bar { ... } 

İndi foo və barı öz proqramınızla birgə istifadə edəcəyinizi bildirək:

 using namespace foo; using namespace bar; void main() { a(42); } 

Bu nöqtədə hər şey düzəldilir. Proqramınızı çalıştırdığınızda, "bir şey edir." Ancaq sonradan paneli yeniləyir və bunun dəyişdiyini deyirsiniz:

 namespace bar { void a(float) {  } } 

Bu nöqtədə bir derleyici hatası alacaksınız:

 using namespace foo; using namespace bar; void main() { a(42); // error: call to 'a' is ambiguous, should be foo::a(42) } 

Beləliklə, "a" nə deməkdir (yəni, foo::a ) aydınlaşdırmaq üçün bəzi saxtakarlıqlar etməlisiniz. Bu, ehtimal ki, arzuolunmazdır, amma xoşbəxtlikdən bu olduqca sadədir (yalnız foo:: əlavə edin: hər şey əvvəlcədən kompilyatorun qeyri-müəyyən olduğunu göstərir).

Ancaq alternativ bir ssenari təsəvvür edin ki, bunun əvəzinə çubuğun belə bir şəkildə dəyişməsi dəyişdi:

 namespace bar { void a(int) {  } } 

Bu nöqtədə, a(42) çağırışınız birdən foo::a əvəzinə bar::a əlavə olunur və bir şey yerinə bir şey etmək tamamilə fərqlidir. Compiler xəbərdarlığı və ya başqa bir şey yoxdur. Proqramınız əvvəllərdən fərqli bir şeylər etməyə başlayır.

Bir ad sahəsi istifadə etdikdə, bənzər bir ssenari riski var, belə ki insanlar ad boşluqları ilə narahatdırlar. Ad boşluğundakı daha çox şey, münaqişənin riski nə qədər böyükdür, buna görə də insanlar ad nominasiyasında std ad boşluğundan istifadə etmək üçün daha da qeyri-adekvat ola bilər (digər adlardan daha çox).

Nəticədə, bu qeyd qabiliyyəti və etibarlılıq / davamlılıq arasında ticarət-off edir. Readability də əhəmiyyətli ola bilər, amma bunun üçün hər hansı bir dəlilləri görə bilərik. Normal olaraq söyləmək olar ki, etibarlılıq və davamlılıq daha vacibdir, amma bu halda daim olduqca nadir bir etibarlılığa / saxlanılmasına görə qeydiyyat xərclərini ödəyəcəksiniz. "Ən yaxşı" ticarət, layihə və prioritetlərinizi müəyyən edəcəkdir.

11
02 сент. Cavab Kevin tərəfindən verildi 02 Sep. 2016-09-02 23:06 '16 at 11:06 pm 2016-09-02 23:06

Ad boşluğu adlandırılmış bir əhatə dairəsidir. Ad boşluqları əlaqədar bildirişləri qruplaşdırmaq və ayrı-ayrı maddələrdən ayrı saxlamaq üçün istifadə olunur. Например, две отдельно разработанные библиотеки могут использовать одно и то же имя для обозначения разных но пользователь может использовать оба:

 namespace Mylib{ template<class T> class Stack{  }; / / ... } namespace Yourlib{ class Stack{  }; / / ... } void f(int max) { Mylib: :Stack<int> s1(max) ; / / use my stack Yourlib: :Stack s2(max) ; / / use your stack / / ... } 

Повторение имени пространства имен может быть отвлечением как для читателей, так и для писателей. Следовательно, возможно чтобы указать, что имена из определенного пространства имен доступны без явной квалификации. Məsələn:

 void f(int max) { using namespace Mylib; / / make names from Mylib accessible Stack<int> s1(max) ; / / use my stack Yourlib: :Stack s2(max) ; / / use your stack / / ... } 

Пространства имен предоставляют мощный инструмент для управления различными библиотеками и различными версиями код. В частности, они предлагают альтернативу программиста того, как явным становится ссылка на нелокальную имя.

Источник: обзор языка программирования С++ by Bjarne Stroustrup

11
ответ дан Rohan Singh 05 апр. '15 в 15:56 2015-04-05 15:56

Я согласен с остальными здесь, но хотел бы затронуть проблемы, связанные с удобочитаемостью - вы можете избежать всего этого, просто используя typedefs в верхней части объявления вашего файла, функции или класса.

Я обычно использую его в своем объявлении класса, поскольку методы в классе имеют дело с похожими типами данных (членами), а typedef - это возможность назначить имя, которое имеет смысл в контексте класса. Это на самом деле помогает читаемости в определениях методов класса.

 //header class File { typedef std::vector<std::string> Lines; Lines ReadLines(); } 

и в реализации:

 //cpp Lines File::ReadLines() { Lines lines; //get them... return lines; } 

в отличие от:

 //cpp vector<string> File::ReadLines() { vector<string> lines; //get them... return lines; } 

və ya

 //cpp std::vector<std::string> File::ReadLines() { std::vector<std::string> lines; //get them... return lines; } 
10
ответ дан Carl 12 февр. '15 в 3:40 2015-02-12 03:40

Пример, в котором использование пространства имен std вызывает ошибку компиляции из-за неоднозначности подсчета, которая также является функцией в библиотеке алгоритмов.

 #include <iostream> using namespace std; int count = 1; int main() { cout<<count<<endl; } 
9
ответ дан Nithin 31 дек. '15 в 11:00 2014-12-31 11:00

Я не думаю, что это обязательно плохая практика при любых условиях, но вам нужно быть осторожным, когда вы ее используете. Если вы пишете библиотеку, вы, вероятно, должны использовать операторы разрешения области видимости с пространством имен, чтобы ваша библиотека не загоняла головы другим библиотекам. Для кода уровня приложения я не вижу в этом ничего плохого.

8
ответ дан Dr. Watson 21 сент. '09 в 6:34 2009-09-21 06:34

Я согласен с другими - он спрашивает о столкновениях имен, двусмысленностях, а затем тот факт, что он менее явный. Хотя я вижу использование using , мое личное предпочтение - ограничить его. Я также решительно рассмотрю то, что некоторые другие отметили:

Если вы хотите найти имя функции, которое может быть довольно распространенным именем, но вы хотите только найти его в пространстве имен std (или наоборот - вы хотите изменить все вызовы, которые НЕ находятся в пространстве имен std , namespace X ,...), то как вы предлагаете это сделать? Вы могли бы написать программу для этого, но не лучше ли тратить время на работу над самим проектом, а не на создание программы для поддержки вашего проекта?

Лично я на самом деле не против std:: prefix. Мне нравится выглядеть больше, чем не иметь его. Я не знаю, потому что это явное и говорит мне: "Это не мой код... я использую стандартную библиотеку", или если это что-то еще, но я думаю, что это выглядит лучше. Это может быть странно, учитывая, что я только недавно попал в C++ (используется и все еще делает C и другие языки намного дольше, а C - мой любимый язык всех времен, прямо над сборкой).

Есть еще одна вещь, хотя она несколько связана с вышесказанным и что другие указывают. Хотя это может быть плохой практикой, я иногда резервирую std::name для стандартной версии библиотеки и имени для реализации конкретной программы. Да, действительно, это может вас укусить и укусить, но все сводится к тому, что я начал этот проект с нуля, и я для него единственный программист. Пример: я перегружаю std::string и называю его string . У меня есть полезные дополнения. Я сделал это частично из-за моей тенденции C и Unix (+ Linux) к именам нижнего регистра.

Кроме того, вы можете иметь псевдонимы пространства имен. Вот пример того, где это полезно, о котором, возможно, не обращалось. Я использую стандарт C++ 11 и, в частности, с libstd C++. Ну, у него нет полной поддержки std::regex . Конечно, он компилируется, но он выдает исключение по тому, что это ошибка на конце программиста. Но это недостаток в реализации. Итак, вот как я это решил. Установите Boost regex и свяжите его. Затем я делаю следующее, чтобы, когда libstd C++ полностью реализовал его, мне нужно только удалить этот блок, а код останется тем же:

 namespace std { using boost::regex; using boost::regex_error; using boost::regex_replace; using boost::regex_search; using boost::regex_match; using boost::smatch; namespace regex_constants = boost::regex_constants; } 

Я не буду спорить о том, плохая идея или нет. Тем не менее я утверждаю, что он сохраняет чистоту для моего проекта и в то же время делает его конкретным: True. Мне нужно использовать Boost, но я использую его, как будто libstd C++ в конечном итоге получит его. Да, начинать свой собственный проект и начинать со стандартного (...) в самом начале очень долгий путь, помогая обслуживанию, развитию и всему, что связано с проектом!

Редактировать:
Теперь, когда у меня есть время, просто что-то прояснить. На самом деле я не считаю целесообразным использовать имя класса/любого в STL намеренно и, более конкретно, вместо. Строка - это исключение (игнорируйте первый, выше или второй здесь, каламбур, если вы должны) для меня, поскольку мне не понравилась идея "String". Как бы то ни было, я все еще очень склонен к C и предвзято относился к C++. Сохраняя детали, многое из того, что я работаю, больше подходит для C (но это было хорошее упражнение и хороший способ сделать себя). Изучите другой язык и b. Попробуйте не быть менее предвзятым против объекта/классов /etc, который, возможно, как менее замкнутый, менее высокомерный, более приемный.). Но полезно то, что некоторые из них уже предлагали: я действительно использую список (он довольно общий, не так ли?), Сортировать (то же самое), чтобы называть два, которые вызовут столкновение имен, если я буду делать using namespace std; и поэтому с этой целью я предпочитаю быть конкретным, контролировать и знать, что, если я намереваюсь, чтобы это было стандартное использование, мне придется его указать. Проще говоря: не допускается.

А что касается создания регулярного выражения Boost std . Я делаю это для будущей интеграции, и, опять же, я полностью признаю, что это предвзятость - я не думаю, что это так же уродливо, как boost::regex::... Для меня это другое дело. В C++ есть много вещей, которые я до сих пор еще не получил, чтобы полностью согласиться на внешний вид и методы (еще один пример: вариативные шаблоны против var args [хотя я допускаю, что вариативные шаблоны очень полезны!]). Даже те, что я принимаю, это было трудно, и у меня все еще есть проблемы с ними.

6
ответ дан user4138451 13 окт. '14 в 20:30 2014-10-13 20:30

Это не ухудшает работу вашего программного обеспечения или проекта, включение пространства имен в начале исходного кода не так уж плохо. Включение инструкции using namespace std с using namespace std зависит от ваших потребностей и того, как вы разрабатываете программное обеспечение или проект.

Пространство namespace std содержит стандартные функции и переменные C++. Это пространство имен полезно, когда вы часто используете стандартные функции C++.

Как упоминается на этой странице :

Утверждение, использующее пространство имен std, обычно считается плохой практикой. Альтернативой этому утверждению является указание пространства имен, к которому принадлежит идентификатор, с помощью оператора области (: :) каждый раз, когда мы объявляем тип.

И посмотрите это мнение :

Нет проблем с использованием "использования пространства имен std" в исходном файле при интенсивном использовании пространства имен и точно знать, что ничего не столкнется.

Некоторые люди говорили, что это плохая практика включать using namespace std в исходные файлы, потому что вы вызываете из этого пространства имен все функции и переменные. Если вы хотите определить новую функцию с тем же именем, что и другая функция, содержащаяся в namespace std вы должны перегрузить функцию, и это может вызвать проблемы из-за компиляции или выполнения. Он не будет компилироваться или исполняться, как вы ожидаете.

Как упоминается на этой странице :

Хотя утверждение не позволяет нам печатать std :: всякий раз, когда мы хотим получить доступ к классу или типу, определенному в пространстве имен std, он импортирует всю полноту пространства имен std в текущее пространство имен программы. Давайте рассмотрим несколько примеров, чтобы понять, почему это может быть не так хорошо

...

Теперь на более позднем этапе разработки мы хотим использовать другую версию cout, которая реализована в некоторой библиотеке под названием "foo" (например)

...

Обратите внимание на то, что существует двусмысленность, на которую указывает точка cout. Компилятор может обнаружить это, а не компилировать программу. В худшем случае программа все еще может компилироваться, но вызывает неправильную функцию, поскольку мы никогда не указывали, к какому пространству имен принадлежал идентификатор.

6
ответ дан CryogenicNeo 23 апр. '18 в 20:15 2018-04-23 20:15

Это плохая практика, часто называемая глобальным загрязнением пространства имен. Проблемы могут возникать, когда более одного пространства имен имеет одно и то же имя функции с сигнатурой, тогда компилятор будет неоднозначным, чтобы решить, какой из них вызывать, и этого можно избежать, когда вы указываете пространство имен с помощью вызова функции, например std::cout , Надеюсь это поможет.:)

6
ответ дан adn.911 30 нояб. '17 в 19:24 2017-11-30 19:24

Это зависит от того, где он находится. Если это общий заголовок, вы уменьшаете значение пространства имен, объединяя его в глобальное пространство имен. Имейте в виду, что это может быть аккуратный способ создания глобальных модулей.

6
ответ дан MathGladiator 21 сент. '09 в 6:15 2009-09-21 06:15

"Почему" using namespace std; "считается плохой практикой в ​​С++?"

Я сказал так: почему набирать 5 дополнительных символов считается громоздким некоторыми?

Рассмотрим, например, написав кусок численного программного обеспечения, почему бы мне даже подумать о загрязнении моего глобального пространства имен, сократив общий "std::vector" до "vector", когда "вектор" является одной из проблемных областей наиболее важных понятий?

6
ответ дан Solkar 13 мая '13 в 18:18 2013-05-13 18:18

С неквалифицированными импортированными идентификаторами вам нужны внешние инструменты поиска, такие как grep, чтобы узнать, где объявляются идентификаторы. Это затрудняет обоснование корректности программы.

5
ответ дан August Karlstrom 11 апр. '13 в 17:22 2013-04-11 17:22

Чтобы ответить на ваш вопрос, я смотрю на это так: практически все программисты (не все) вызывают пространство имен std. Поэтому нужно привыкнуть НЕ использовать вещи, которые сталкиваются или используют те же имена, что и в пространстве имен std. Это очень много, но не столько по сравнению с количеством возможных когерентных слов и псевдонимов, которые могут быть придуманы строго.

Я имею в виду действительно... говоря "не полагайтесь на это присутствующее", просто заставляет вас полагаться на него, не присутствуя. У вас постоянно возникают проблемы с заимствованием фрагментов кода и их постоянным ремонтом. Просто держите свой пользовательский и заимствованный материал в ограниченном объеме, как и должно быть, и быть ОЧЕНЬ щадящим с глобальными (честно глобалы должны почти всегда быть последним средством для целей "компиляции сейчас, здравомыслия позже" ). По-моему, это плохой совет от вашего учителя, потому что использование std будет работать как для "cout", так и для "std:: cout", но НЕ использовать std будет работать только для "std:: cout". Вы не всегда будете достаточно удачливы, чтобы написать свой собственный код.

Qeyd. Не сосредотачивайтесь слишком много на проблемах эффективности, пока вы не узнаете немного о том, как работают компиляторы. С небольшим опытом кодирования вам не нужно много узнавать о них, прежде чем вы поймете, насколько они могут обобщить хороший код во что-то простое. Каждый бит такой же простой, как если бы вы написали все это в C. Хороший код настолько сложный, насколько он должен быть.

5
ответ дан Noneyo Getit 27 июня '13 в 23:33 2013-06-27 23:33

Из моего опыта, если у вас есть несколько библиотек, которые используют, скажем, cout , но для другой цели вы можете использовать неправильный cout .

Например, если я набираю using namespace std; и using namespace otherlib; и набираю только cout (что бывает в обоих), а не std::cout (или 'otherlib::cout' ), вы можете использовать неправильный, и получить ошибки, гораздо эффективнее и эффективнее использовать std::cout .

5
ответ дан Engine Dev 21 авг. '16 в 1:55 2016-08-21 01:55
  • 1
  • 2

Другие вопросы по меткам или Задайте вопрос