2011-03-20 7 views
7

मेरे पास मेरे प्रोग्राम में एक सहायक वर्ग है जिसमें मेरे कार्यक्रम के विभिन्न वर्गों में कई स्थिर कार्य हैं। जैसेकई अनुवाद इकाइयों में कॉपी किए गए C++ में स्थिर सदस्य फ़ंक्शन हैं?

helper.h:

Class helper { 
public: 
    static void fn1() 
    { /* defined in header itself */ } 

    /* fn2 defined in src file helper.cpp */ 
    static void fn2(); 
} 

हेल्पर केवल स्थिर सदस्य कार्य करती है। इसलिए, अन्य मॉड्यूल द्वारा सहायक की कोई वस्तु नहीं बनाई जाती है। सहायक कार्यों जैसे अन्य मॉड्यूल में उपयोग किया जाता है:

A.cpp

#include "helper.h" 
A::foo() { 
    helper::fn1(); 
    helper::fn2(); 
} 

B.cpp

#include "helper.h" 
B::foo() { 
    helper::fn1(); 
    helper::fn2(); 
} 

संकलक A.cpp और B.cpp में सहायक कार्यों के अलग प्रतियां बनाने करता है? मैंने कुछ पूर्व पदों को पढ़ा और मैंने जवाबों से इकट्ठा किया कि संकलक ऐसा करेगा। लेकिन जब मैं fn1 और fn2printf("Address of fn1 is %p\n", &helper::fn1); और printf("Address of fn1 is %p\n", &helper::fn1); के A.cpp और B.cpp दोनों के पते को मुद्रित करता हूं, तो मुझे वही पता मिलता है। अब मैं उलझन में हूँ। क्या कोई स्पष्टीकरण दे सकता है, अगर मुझे कुछ याद आ रहा है।

कारण मैं सहायक कार्यों की कई प्रतियों (यदि ऐसा होता है) के बारे में चिंतित है, तो हम अपने निष्पादन योग्य आकार को कम करने की कोशिश कर रहे हैं और इसे अनुकूलित करना चाहते हैं।

उत्तर

8

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

हालांकि, इनलाइनिंग प्रक्रिया फ़ंक्शन की कई प्रतियां बना सकती है, संकलन इकाइयों की संख्या से भी अधिक। अक्सर कोड को डुप्लिकेट करने का बढ़ता आकार तर्क गुजरने और कार्य कॉल ओवरहेड को समाप्त करने के साथ-साथ सामान्य उप-संपीड़न उन्मूलन के अवसरों को समाप्त करके संभव ऑप्टिमाइज़ेशन द्वारा ऑफ़सेट किया जाता है। हालांकि इनलाइनिंग को आकार और गति के बीच अक्सर ट्रेडऑफ माना जाता है, आकार बढ़ता है अक्सर नगण्य या नकारात्मक भी होता है।

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

+0

+1। मुझे सवाल थोड़ा और सावधानी से पढ़ना चाहिए था;) मेरी पोस्ट हटा दी गई। – Mahesh

+0

@snkrish: क्या यह एक टेम्पलेट स्थिर सदस्य फ़ंक्शन या टेम्पलेट स्थिर वैश्विक फ़ंक्शन है? यदि यह स्थिर सदस्य फ़ंक्शन है, तो आपको शायद टेम्पलेट पैरामीटर के प्रत्येक संयोजन के लिए एक नई प्रति प्राप्त होगी, लेकिन संकलन इकाइयों की संख्या अभी भी प्रभावित नहीं होगी। यदि एक स्थिर वैश्विक (या नामस्थान) फ़ंक्शन, तो आपको प्रत्येक संकलन इकाई में एक नई प्रति प्राप्त होगी। –

+0

विस्तृत उत्तर के लिए धन्यवाद, अब मैं देखता हूं कि पता क्यों समान था। मेरे पास एक फॉलो अप प्रश्न है, मुझे यकीन नहीं है कि मुझे एक अलग पोस्ट शुरू करना चाहिए या नहीं। यदि उपरोक्त वही fn2 टेम्पलेट्स का उपयोग करके लिखा गया था: टेम्पलेट स्थैतिक शून्य fn2(); - क्या स्वयं को हेडर में परिभाषित किया जाना चाहिए या क्या मुझे निष्पादन योग्य आकार को अनुकूलित करने के लिए बाहरी टेम्पलेट सहायक :: fn2() {/ * helper.cpp * /} में परिभाषा का उपयोग करना चाहिए। संकलक फ़ंक्शन की एक प्रति बनायेगा, जब भी एफएन 2 को एक अलग टी के साथ बुलाया जाता है, भले ही इसे कैसे परिभाषित किया जाए? – cppcoder

2

यदि दृश्यमान (उदा।, कक्षा घोषणा में परिभाषित) है, तो यह निश्चित रूप से कई संकलकों द्वारा इनलाइन घोषित किया गया है।

यदि इनलाइन किया गया है, तो हाँ कुछ मामलों में उल्लिखित किया जा सकता है, कुछ मामलों में उल्लिखित, और आंशिक रूप से अन्य मामलों में रेखांकित किया गया है।

यह एक परिभाषा नियम (ओडीआर) का पालन करता है, कई अनुवादों में पाई गई प्रतियां हटाए जाने पर हटा दी जाएंगी (जब तक कि आप निजी बाहरी इनलाइन सक्षम नहीं करते हैं, तो आप वास्तव में अनावश्यक निर्यात कार्यान्वयन के साथ समाप्त हो सकते हैं)।

यदि आप सी से आ रहे हैं: स्थैतिक इस मामले में फ़ंक्शन की एक अनूठी प्रति नहीं बनाता है - इसका मतलब यह है कि आप उस वर्ग के उदाहरण के बिना फ़ंक्शन को कॉल कर सकते हैं जो इसे घोषित करता है।

+0

धन्यवाद मैं एक सहायक वस्तु बनाने के बिना केवल fn1 और fn2 को कॉल करने के लिए स्थिर का उपयोग कर रहा हूं। – cppcoder

+0

@ श्रीकृष्ण मैं इसे देखता हूं। मैंने केवल इसका उल्लेख किया क्योंकि सी प्रोग्रामर लिंक को प्रभावित करने के लिए स्थिर के रूप में घोषित कार्यों के आदी हैं (जो प्रत्येक ज्ञात उपयोग में उल्लिखित नहीं होने पर निजी प्रतियां उत्पन्न करेंगे - प्रश्न के लिए प्रासंगिक)। यह उनके लिए भ्रम का एक आम स्रोत है। उस वजह से, और चूंकि मुझे आपकी पृष्ठभूमि नहीं पता ... मैंने अंतिम विवरण जोड़ा। – justin

0

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

हालांकि, की बहुत अधिनियम पता समारोह समारोह का एक उदाहरण बनाने के लिए संकलक के लिए बाध्य करेगा की लेने, और यह ओडीआर लागू है और इसलिए यह सुनिश्चित करें कि आप हमेशा पाने के लिए संकलन प्रणाली की समस्या है वही पता

संबंधित मुद्दे