दिलचस्प पोस्ट
जो कि प्रोजेक्ट हेडर फाइल Xcode में शामिल होगा नियंत्रित करेगा नि: शुल्क इंटरनेट ब्राउज़र? एसक्यूएल पंक्तियों को हटाएं जहां आईडी को किसी अन्य तालिका से मैच नहीं मिलता है अजगर का "सुपर" सही काम कैसे करता है? SQL सर्वर में अद्वितीय पहचान करने के लिए varchar परिवर्तित करें पूंछ- F के एक अजगर समतुल्य को कैसे लागू किया जाए? कैसे रस्सी में एक सरणी के रूप में एक टुकड़ा पाने के लिए? एंड्रॉइड में एक अनुरोध में एक छवि और ऑडियो अपलोड करें रनटाइम पर फ़ॉन्ट सेट करें, Textview तयशुदा आदेश का डिफ़ॉल्ट मान, नेस्टेड DropDownListFor नहीं का चयन मूल्य फोर्स Google खाता चयनकर्ता MySQL डाइक्रोट्रिक असंवेदनशील खोज (स्पेनिश उच्चारण) Xcode – सापेक्ष पथ के साथ काम करने के लिए force_load प्राप्त करें ध्वज के साथ अजगर re.sub सभी घटनाओं को प्रतिस्थापित नहीं करता है

हेडर में सी + इनलाइन फ़ंक्शन क्यों हैं?

एनबी यह इनलाइन फ़ंक्शंस का उपयोग कैसे करें या वे कैसे काम करते हैं, इसके बारे में कोई सवाल नहीं है, और यही कारण है कि वे किस तरह से किए गए हैं।

कक्षा सदस्य समारोह की घोषणा को फ़ंक्शन को inline रूप में परिभाषित करने की आवश्यकता नहीं है, यह केवल फ़ंक्शन के वास्तविक कार्यान्वयन है। उदाहरण के लिए, हेडर फ़ाइल में:

 struct foo{ void bar(); // no need to define this as inline } 

तो क्लाइंट फ़ंक्शन का इनलाइन कार्यान्वयन हेडर फ़ाइल में क्यों होना चाहिए? मैं इनलाइन फ़ंक्शन को .cpp फ़ाइल क्यों नहीं रख सकता? यदि मैं .cpp फ़ाइल में इनलाइन परिभाषा को डालने का प्रयास करने की कोशिश करता हूं तो मुझे निम्न की एक त्रुटि मिलेगी:

 error LNK2019: unresolved external symbol "public: void __thiscall foo::bar(void)" (?bar@foo@@QAEXXZ) referenced in function _main 1>C:\Users\Me\Documents\Visual Studio 2012\Projects\inline\Debug\inline.exe : fatal error LNK1120: 1 unresolved externals 

Solutions Collecting From Web of "हेडर में सी + इनलाइन फ़ंक्शन क्यों हैं?"

एक inline फ़ंक्शन की परिभाषा को हेडर फाइल में होना नहीं है, लेकिन इनलाइन फ़ंक्शंस के लिए एक परिभाषा नियम की वजह से फ़ंक्शन के लिए एक समान परिभाषा प्रत्येक अनुवाद इकाई में मौजूद है जो इसका उपयोग करती है।

यह प्राप्त करने का सबसे आसान तरीका है हेडर फ़ाइल में परिभाषा डाल कर।

यदि आप एक स्रोत फ़ाइल में एक फ़ंक्शन की परिभाषा डालनी चाहते हैं तो आपको इसे inline घोषित नहीं करना चाहिए। फ़ंक्शन को inline घोषित नहीं किया गया है इसका मतलब यह नहीं है कि कंपाइलर फ़ंक्शन को इनलाइन नहीं कर सकता।

चाहे आपको एक फ़ंक्शन inline घोषित करनी चाहिए या नहीं, यह आमतौर पर एक विकल्प है जिसे आपको एक परिभाषा के संस्करण के आधार पर करना चाहिए जो आपके लिए अनुपालन करने के लिए सबसे अधिक समझदारी बनाता है; inline जोड़ना और उसके बाद की बाधाओं से प्रतिबंधित होने से थोड़ा सा मतलब हो जाता है

इसे देखने के दो तरीके हैं:

  1. इनलाइन फ़ंक्शन हेडर में घोषित किए गए हैं, क्योंकि एक फ़ंक्शन कॉल को इनलाइन करने के लिए, संकलक को फ़ंक्शन बॉडी को देखने में सक्षम होना चाहिए। ऐसा करने के लिए एक सरल कम्पाइलर के लिए, फ़ंक्शन बॉडी कॉल के रूप में एक ही अनुवाद इकाई में होना चाहिए। (एक आधुनिक कंपाइलर अनुवाद इकाइयों में अनुकूलित कर सकता है, और इसलिए फ़ंक्शन कॉल को इनलाइन किया जा सकता है, हालांकि फ़ंक्शन परिभाषा एक अलग अनुवाद इकाई में है, लेकिन ये ऑप्टिमाइज़ेशन महंगे हैं, हमेशा सक्षम नहीं होते हैं, और हमेशा समर्थित नहीं होते हैं संकलक)

  2. हेडर में घोषित कार्यों को inline चिह्नित किया जाना चाहिए क्योंकि अन्यथा प्रत्येक अनुवाद इकाई में हेडर में फ़ंक्शन की परिभाषा होगी, और लिंकर कई परिभाषाओं (एक परिभाषा नियम का उल्लंघन) के बारे में शिकायत करेगा। inline कीवर्ड इस को दबा देते हैं, जिससे एकाधिक अनुवाद इकाइयों (समान) परिभाषाओं को शामिल किया जा सकता है।

दो स्पष्टीकरण वास्तव में इस तथ्य को उबालते हैं कि inline कीवर्ड वास्तव में ठीक नहीं करता जो आपको अपेक्षित था।

एक सी + + कंपाइलर इनलाइनिंग ऑप्टिमाइज़ेशन (जिसे फ़ंक्शन कॉल के फ़ंक्शन को कॉल करने की सुविधा देता है, कॉल ओवरहेड को सहेजते हैं) को लागू करने के लिए स्वतंत्र है, जब तक कि यह प्रोग्राम के अवलोकन व्यवहार को बदल नहीं करता है।

inline कीवर्ड ने कंपलर के लिए यह अनुकूलन लागू करने के लिए आसान बनाता है, फ़ंक्शन परिभाषा को कई अनुवाद इकाइयों में दिखाई देने की अनुमति देकर, लेकिन कीवर्ड का उपयोग करने का अर्थ यह नहीं है कि कंपाइलर को फ़ंक्शन को इनलाइन करना है, और कीवर्ड का उपयोग नहीं करना है। टी समारोह में इनलाइनिंग से कंपाइलर मना करना

यह सी ++ कंपाइलर की एक सीमा है यदि आप फ़ंक्शन को हेडर में डालते हैं, तो सभी सीपीपी फ़ाइलें जहां इनलाइन लगाई जा सकती हैं, आपके फ़ंक्शन के "स्रोत" को देख सकते हैं और इनलाइनिंग को कंपाइलर द्वारा किया जा सकता है। अन्य करें लिंकिंगर द्वारा इनलाइनिंग करना होगा (प्रत्येक सीपीपी फाइल को ओबीजे फाइल में अलग से संकलित किया गया है)। समस्या यह है कि यह लिंकर में ऐसा करना बहुत मुश्किल होगा। ऐसी ही समस्या "टेम्पलेट" वर्ग / फ़ंक्शंस के साथ मौजूद है। उन्हें कंपाइलर द्वारा तत्काल बनाने की आवश्यकता है, क्योंकि लिंकर को तत्काल (एक विशेष संस्करण का निर्माण) उन्हें समस्या होनी चाहिए। कुछ नए संकलक / लिंकर "दो पास" संकलन / लिंकिंग कर सकते हैं जहां कंपाइलर पहले पास करता है, तो लिंकर इसका काम करता है और अनसुलझे चीजों को हल करने के लिए कंपाइलर को कॉल करता है (इनलाइन / टेम्प्लेट्स …)

इसका कारण यह है कि संकलक को वास्तव में यह देखने के लिए कि उसे कॉल के स्थान पर छोड़ने में सक्षम होना है।

याद रखें कि सी और सी ++ एक बहुत ही सरलीकृत संकलन मॉडल का उपयोग करते हैं, जहां संकलक हमेशा एक समय में एक अनुवाद इकाई देखता है। (यह निर्यात के लिए विफल रहता है, जो मुख्य कारण है कि केवल एक विक्रेता वास्तव में इसका कार्यान्वयन करता है।)

सी + inline कीवर्ड भ्रामक है, इसका अर्थ "इस फ़ंक्शन को इनलाइन" नहीं करता है। अगर फ़ंक्शन को इनलाइन के रूप में परिभाषित किया जाता है, तो इसका मतलब है कि सभी परिभाषाएं बराबर हैं, तब तक इसे कई बार परिभाषित किया जा सकता है। यह एक ऐसा फ़ंक्शन चिह्नित करने के लिए पूरी तरह से कानूनी है जो inline को वास्तविक फ़ंक्शन बनने के लिए कहा जाता है जिसे उस बिंदु पर लिखे गए कोड के बजाय कहा जाता है जहां इसे कहा जाता है।

टेम्पलेट्स के लिए हेडर फ़ाइल में किसी फ़ंक्शन को परिभाषित करना आवश्यक है, क्योंकि उदाहरण के लिए एक टेम्पलटेड क्लास वास्तव में एक क्लास नहीं है, यह एक क्लास के लिए एक टेम्पलेट है जिसे आप कई विविधताएं बना सकते हैं। कंपाइलर के लिए, उदाहरण के लिए Foo<int>::bar() फ़ंक्शन करें जब आप फू क्लास बनाने के लिए फ़ू टेम्पलेट का उपयोग करते हैं , तो Foo<T>::bar() की वास्तविक परिभाषा दिखाई देनी चाहिए ।

क्योंकि कंपाइलर को उन्हें इनलाइन करने के लिए देखने की आवश्यकता है और हेडर फ़ाइलों को "घटक" कहा जाता है जो आमतौर पर अन्य अनुवाद इकाइयों में शामिल होते हैं।

 #include "file.h" // Ok, now me (the compiler) can see the definition of that inline function. // So I'm able to replace calls for the actual implementation. 

मुझे पता है कि यह एक पुरानी धागा है, लेकिन मुझे लगता है कि extern कीवर्ड का उल्लेख करना चाहिए। मैंने हाल ही में इस मुद्दे पर भाग लिया है और इस प्रकार हल किया है

Helper.h

 namespace DX { extern inline void ThrowIfFailed(HRESULT hr); } 

Helper.cpp

 namespace DX { inline void ThrowIfFailed(HRESULT hr) { if (FAILED(hr)) { std::stringstream ss; ss << "#" << hr; throw std::exception(ss.str().c_str()); } } }