परिचय: C++ के लिए स्वच्छ कोड क्यों महत्वपूर्ण है?
\n\nC++ एक शक्तिशाली और लचीली भाषा है जो आपको अत्यधिक कुशल सिस्टम कोड से लेकर जटिल एप्लिकेशन तक कुछ भी लिखने की अनुमति देती है। हालांकि, यह लचीलापन अक्सर अव्यवस्था का कारण बनता है: ओवरलोडेड फंक्शन, इम्प्लिसिट कन्वर्ज़न, मैन्युअल मेमोरी मैनेजमेंट और मैक्रोज़ कुछ ही महीनों में आपके प्रोजेक्ट को 'दलदल' में बदल सकते हैं। रॉबर्ट मार्टिन द्वारा लोकप्रिय Clean Code की अवधारणा C++ पर पूरी तरह से लागू होती है, लेकिन भाषा की विशिष्टताओं को ध्यान में रखते हुए।
\n\nइस लेख में, हम C++ में स्वच्छ कोड के प्रमुख सिद्धांतों को समझेंगे और वास्तविक उदाहरणों के साथ उनके अनुप्रयोग को दिखाएंगे। आप सीखेंगे कि ऐसा कोड कैसे लिखें जिसे पढ़ना, परीक्षण करना और बनाए रखना आसान हो।
\n\n1. नामकरण और संरचना: पठनीयता की नींव
\n\n1.1. सार्थक वेरिएबल और फंक्शन नाम
\n\nस्वच्छ कोड का पहला नियम यह है कि नाम से इरादा स्पष्ट होना चाहिए। C++ में ओवरलोडिंग और टेम्पलेट्स के कारण यह विशेष रूप से महत्वपूर्ण है।
\n\nखराब उदाहरण:
\n\nint d; // दिनों में बीता समय\nvoid proc(int a, int b); // a और b क्या हैं?\n\nअच्छा उदाहरण:
\n\nint elapsedTimeInDays;\nvoid processData(const std::vector<int>& inputData, int maxIterations);\n\n1.2. क्लासेस और नेमस्पेस
\n\nतार्किक समूहीकरण के लिए नेमस्पेस का उपयोग करें। ग्लोबल वेरिएबल्स से बचें - यह एक एंटी-पैटर्न है।
\n\nnamespace network {\n class TcpConnection {\n public:\n void connect(const std::string& host, int port);\n void send(const std::vector<char>& data);\n private:\n int socket_;\n };\n} // namespace network\n\n2. फंक्शन: छोटे और एकल जिम्मेदारी वाले
\n\n2.1. एकल जिम्मेदारी का सिद्धांत (SRP)
\n\nएक फंक्शन को केवल एक ही काम करना चाहिए। यदि कोई फंक्शन एक से अधिक काम करता है, तो उसे विभाजित करें।
\n\nखराब उदाहरण:
\n\nvoid processOrder(Order& order) {\n // वैलिडेशन\n if (order.total < 0) throw std::invalid_argument("Negative total");\n // डेटाबेस में सेव करना\n database.save(order);\n // ईमेल भेजना\n emailService.send(order.customerEmail, "Order confirmed");\n}\n\nअच्छा उदाहरण:
\n\nbool validateOrder(const Order& order);\nvoid saveOrderToDatabase(const Order& order);\nvoid sendConfirmationEmail(const Order& order);\n\nvoid processOrder(Order& order) {\n if (!validateOrder(order)) return;\n saveOrderToDatabase(order);\n sendConfirmationEmail(order);\n}\n\n2.2. साइड इफेक्ट्स से बचें
\n\nफंक्शन को बिना स्पष्ट आवश्यकता के ग्लोबल स्टेट नहीं बदलना चाहिए। कॉन्स्टेंट रेफरेंस का उपयोग करें और आर्गुमेंट्स को बदलने के बजाय वैल्यू लौटाएं।
\n\n// खराब: इनपुट वेक्टर को बदलता है\nvoid addPrefix(std::vector<std::string>& words, const std::string& prefix) {\n for (auto& word : words) {\n word = prefix + word;\n }\n}\n\n// अच्छा: नया वेक्टर लौटाता है\nstd::vector<std::string> addPrefix(const std::vector<std::string>& words, const std::string& prefix) {\n std::vector<std::string> result;\n result.reserve(words.size());\n for (const auto& word : words) {\n result.push_back(prefix + word);\n }\n return result;\n}\n\n3. मेमोरी मैनेजमेंट और RAII
\n\n3.1. स्मार्ट पॉइंटर्स का उपयोग करें
\n\nआधुनिक C++ (C++11 और उससे नए) में new/delete के माध्यम से मैन्युअल मेमोरी मैनेजमेंट को पुराना माना जाता है। std::unique_ptr और std::shared_ptr का उपयोग करें।
// खराब: मेमोरी लीक संभव है\nvoid process() {\n Resource* res = new Resource();\n // ... अगर यहां एक्सेप्शन आता है, तो मेमोरी लीक हो जाएगी\n delete res;\n}\n\n// अच्छा: स्वचालित रिलीज\nvoid process() {\n a