C++ में using namespace std: यह क्यों बुरा है और वास्तव में कैसे काम करता है

शुरुआती लोगों के लिए ऑनलाइन Python प्रशिक्षक

Python आसानी से सीखें बिना सिद्धांत के बोझ के। स्वचालित जांच के साथ व्यावहारिक कार्य हल करें और ब्राउज़र में सीधे कोड लिखें।

पाठ्यक्रम शुरू करें

«using namespace std;» — दोस्त या दुश्मन? सूक्ष्मदर्शी से विश्लेषण

\n\n

यदि आपने कभी C++ में कोड लिखा है (विशेषकर शुरुआत में), तो आपने शायद अपने प्रोग्राम की शुरुआत इस जादुई पंक्ति से की होगी:

\n\n
#include <iostream>\nusing namespace std;\n\nint main() {\n    cout << "Hello, world!" << endl;\n    return 0;\n}
\n\n

सब कुछ काम करता है, कोड कंपाइल हो जाता है, जीवन सुंदर है। लेकिन समय बीतता है — और आप Stack Overflow पर हजारों बार देखे गए एक प्रश्न पर ठोकर खाते हैं: «What's the problem with "using namespace std;"?»। या, इससे भी बुरा, आपको काम पर एक कोड रिव्यू मिलता है जिसमें लाल निशान होता है: «using namespace std हटाओ, यह एक बुरी प्रथा है»।

\n\n

क्यों? आइए समझते हैं कि वास्तव में इस डायरेक्टिव के पर्दे के पीछे क्या होता है, और कब इसका उपयोग आपके कोड को एक बारूदी सुरंग में बदल सकता है।

\n\n

वास्तव में «using namespace std;» क्या है?

\n\n

समस्या को समझने के लिए, हमें C++ की मानक लाइब्रेरी में झांकना होगा। कल्पना करें कि मानक लाइब्रेरी एक विशाल गोदाम है, जहाँ हजारों अलग-अलग वस्तुएँ रखी हैं: cout, vector, string, find, sort इत्यादि। ये वस्तुएँ बक्सों (नाम स्थानों) में बड़ी सावधानी से रखी गई हैं।

\n\n

नाम स्थान std — ऐसा ही एक बक्सा है। जब आप लिखते हैं:

\n\n
std::cout << "नमस्ते!";
\n\n

आप कंपाइलर से कह रहे हैं: «std बक्से से cout ऑब्जेक्ट लो»। सब कुछ स्पष्ट और समझने योग्य है।

\n\n

लेकिन using namespace std; — यह बक्से को खोलकर उसकी सारी सामग्री फर्श पर फैलाने जैसा है। अब कंपाइलर इन सभी नामों को ऐसे देखता है जैसे वे सीधे आपके प्रोग्राम में घोषित किए गए हों। आप std::cout के बजाय cout लिख सकते हैं, std::endl के बजाय endl — सुविधाजनक है, है ना?

\n\n

लेकिन इस सिक्के का दूसरा पहलू भी है।

\n\n

मुख्य समस्या: नाम टकराव (name clash)

\n\n

कल्पना करें कि आप ग्राफिक्स के साथ काम करने के लिए अपनी लाइब्रेरी लिख रहे हैं। आपके पास एक फंक्शन drawLine है और... एक वेरिएबल count है। सब कुछ ठीक है, जब तक आप using namespace std; को शामिल नहीं करते।

\n\n

अब कल्पना करें कि std में आपके जैसे ही नाम का कोई फंक्शन या ऑब्जेक्ट है। या — इससे भी बुरा — आप किसी और की लाइब्रेरी का उपयोग कर रहे हैं, जिसमें count है (और ऐसा ऑब्जेक्ट एल्गोरिदम के भाग के रूप में std:: में मौजूद है)।

\n\n

वास्तविक जीवन का उदाहरण:

\n\n
#include <iostream>\n#include <algorithm>\nusing namespace std;\n\nint count = 10; // हमारा वेरिएबल\n\nint main() {\n    int arr[] = {1, 2, 3, 4, 5};\n    // त्रुटि! कंपाइलर समझ नहीं पाता कि आप किस count का मतलब रखते हैं\n    // std::count (फंक्शन) या हमारा int count?\n    cout << count(arr, arr + 5, 3) << endl;\n    return 0;\n}
\n\n

यह कोड कंपाइल नहीं होगा या, इससे भी खतरनाक, अप्रत्याशित व्यवहार के साथ कंपाइल हो सकता है। कंपाइलर std::count ( से फंक्शन) और आपके वेरिएबल count के बीच भ्रमित हो जाएगा।

\n\n

यही नाम टकराव — मुख्य कारण है कि अनुभवी C++ डेवलपर्स वैश्विक दायरे में using namespace std; से बचते हैं।

\n\n

यह अंदरूनी रूप से कैसे काम करता है: नाम खोज तंत्र

\n\n

आइए कंपाइलर के अंदर झांकते हैं। जब कंपाइलर किसी नाम (जैसे, cout) का सामना करता है, तो वह एक प्रक्रिया शुरू करता है जिसे नाम खोज (name lookup) कहा जाता है। कंपाइलर वर्तमान दायरे में, फिर मूल दायरे में, और इसी तरह इस नाम की घोषणा खोजता है।

\n\n

डायरेक्टिव using namespace std; नाम स्थान std के सभी नामों को वर्तमान दायरे में जोड़ता है। तकनीकी रूप से इसे using डायरेक्टिव कहा जाता है। यह नई घोषणाएँ नहीं बनाता, बल्कि केवल नामों को खोज के लिए दृश्यमान बनाता है।

\n\n

कंपाइलर स्तर पर यह इस तरह दिखता है:

\

ब्लॉग

पुस्तक अनुशंसाएँ