दिलचस्प पोस्ट
JQuery के साथ इनपुट वैल्यू सेट करने के बाद एन्जिलर मॉडल को अपडेट करें कैरेक्टर स्टेटस को संरक्षित करने के साथ स्व-पूर्णतया सबूत के लिए गतिशील रूप से सुझाव कैसे जोड़ें .NET का उपयोग करते हुए एक निर्देशिका में सबसे हाल की फ़ाइल को कैसे ढूंढें, और बिना पाशन? रेल में POST का उपयोग करने के लिए redirect_to IOS7 में UIAlertView ऐडस्यूबव्यू अनुशंसित सर्विस स्टैक्स एपीआई संरचना सेलेनियम वेबड्रायवर को तत्व पर क्लिक करने के लिए मजबूर कैसे करें, जो वर्तमान में दिखाई नहीं दे रहा है? क्या जावा में स्मृति अपवाद को पकड़ना संभव है? अजगर स्क्रिप्ट के माध्यम से एक स्क्रीनशॉट लें जेएस ली टैग onclick IE8 पर काम नहीं कर रहा है बाश में हैश टेबल कैसे परिभाषित करें? सी # में एरे की कॉपी करने का कोई तेज़ तरीका है? SPARQL क्वेरी से एकत्रित परिणाम कैसे जूनिट परीक्षण उपकरण के साथ शून्य विधि का परीक्षण करने के लिए? अस्थायी बिंदु समानता का परीक्षण करना

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

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

कक्षा सदस्य समारोह की घोषणा को फ़ंक्शन को 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 

वेब के समाधान से एकत्रित समाधान "हेडर में सी + इनलाइन फ़ंक्शन क्यों हैं?"

एक 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()); } } }