2011-10-20 12 views
11

आप हेडर फाइल में कार्यशील परिभाषाएँ डाल करने के लिए चाहते हैं, तो ऐसा लगता है तीन अलग अलग समाधान देखते हैं: के रूप में inline डाल समारोह परिभाषाओं

  • static
  • के रूप में समारोह को चिह्नित

    1. समारोह का प्रतीक फ़ंक्शन को अज्ञात नेमस्पेस

    (हाल ही में, मुझे # 1 के बारे में भी पता नहीं था।) तो इन समाधानों में अंतर क्या हैं, और जब मैं sh क्या मैं पसंद करूंगा? मैं हेडर-केवल दुनिया में हूं, इसलिए मुझे हेडर फ़ाइलों में परिभाषाओं की वास्तव में आवश्यकता है।

  • +8

    आप भूल गए: उन्हें फ़ंक्शन टेम्पलेट्स में बदलें। यही वह है जो मैं आमतौर पर पसंद करता हूं। – sbi

    +1

    स्थिर का उपयोग न करें जो कई अलग-अलग प्रतियों और पागलपन की ओर जाता है। –

    +2

    "प्रत्येक अज्ञात नेमस्पेस में एक प्रति" समाधान एक ही पागलपन की ओर जाता है। – MSalters

    उत्तर

    11

    के लिए अलग है static और अज्ञात नेमस्पेस संस्करण समान होते हैं: प्रत्येक अनुवाद इकाई में इसका कार्य का स्वयं का संस्करण होगा, और इसका मतलब है कि एक स्थिर फ़ंक्शन f दिया गया है, सूचक &f प्रत्येक अनुवाद इकाई में अलग होगा, और कार्यक्रम में एन होगा f के विभिन्न संस्करण (बाइनरी में अधिक कोड)।

    यह नहीं सही दृष्टिकोण एक शीर्षक में एक समारोह प्रदान करने के लिए है, यह एन अलग (वास्तव में बराबर) कार्यों प्रदान करती है। इस अधिक स्पष्ट करने के लिए:: तो क्या आप चाहते हैं के बिना एक शीर्षक में एक समारोह की परिभाषा प्रदान करना है समारोह static स्थानीय लोगों में शामिल है, तो वहाँ एन अलग static स्थानीय चर ...

    संपादित हो जाएगा एक परिभाषा नियम तोड़ना, सही दृष्टिकोण है कार्य को inline बनाना।

    +0

    तो 'इनलाइन' सही दृष्टिकोण है? यह अच्छा होगा अगर आपने यह स्पष्ट किया। – fredoverflow

    +0

    इस पर मेरी समझ समान थी और मैंने इसे एक उत्तर के रूप में पोस्ट किया लेकिन फिर मैंने इसे हटा दिया, चूंकि मैं क्यू के साथ थोड़ा फंस गया था, 'हेडर में परिभाषित फ़ंक्शन को इनलाइन के रूप में कैसे परिभाषित किया गया है, यह ओडीआर को बाईपास करता है?', मैंने सोचा कि' धारा $ 3.2/5' इसे संबोधित करता है लेकिन मुझे यकीन नहीं था। यह क्यू में तलाशने की तुलना में शायद अधिक विस्तार से है लेकिन क्या आप कृपया इस पर विस्तृत जानकारी दे सकते हैं। –

    +0

    @ एएलएस: 3.2/3 * प्रत्येक कार्यक्रम में उस कार्यक्रम में उपयोग किए जाने वाले प्रत्येक गैर-इनलाइन फ़ंक्शन या ऑब्जेक्ट की बिल्कुल एक परिभाषा होगी; कोई निदान की आवश्यकता नहीं है। [...] एक इनलाइन फ़ंक्शन को प्रत्येक अनुवाद इकाई में परिभाषित किया जाएगा जिसमें इसका उपयोग किया जाता है। * (सी ++ 03 से वार्डिंग, लेकिन यह सी ++ 11 में पाया जा सकता है जहां * इस्तेमाल * है * ओडीआर-प्रयुक्त *) –

    0

    static फ़ंक्शंस (अज्ञात नेमस्पेस के समतुल्य) प्रत्येक टीयू के लिए अलग-अलग प्रतियां प्राप्त करते हैं। यदि फ़ंक्शन पुन: प्रवेशकर्ता है तो यह मूल रूप से समान है (कुछ कंपाइलरों में असेंबली-स्तर अंतर हो सकते हैं) लेकिन यदि ऐसा नहीं है तो प्रत्येक टीयू के लिए अलग-अलग स्थिर डेटा होगा। इनलाइन फ़ंक्शंस को फोल्ड किया जाता है- यानी, उनके पास प्रत्येक टीयू के लिए स्थिर डेटा की केवल एक प्रति है।

    +1

    @ टोनीके: हालांकि मैं abbrevatons का उपयोग न करने और पूर्ण नोटेशन का उपयोग करने के सुझाव से सहमत हूं, मैं दृढ़ता से असहमत हूं कि 'ओपी स्पष्ट रूप से एक विशेषज्ञ नहीं है'। ओपी एसओ में कुछ विशेषज्ञों में से एक है जो वास्तव में सी ++ को समझता है कोर। –

    +2

    ठीक है, मैंने अपनी टिप्पणी हटाने का फैसला किया है, लेकिन बहुत देर हो चुकी है ... तो मुझे इसे यहां पुन: स्थापित करने दें: टीयू जैसे संक्षेप का उपयोग करने से आपके पाठक में अनुभव का स्तर लगता है जो आपकी व्याख्या को अनिवार्य रूप से प्रस्तुत करता है। (जाहिर है, आपका पाठक फ्रेडओवरफ्लो है।) और बीटीडब्ल्यू, इसका मतलब अनुवाद इकाई है। – TonyK

    4

    जहां तक ​​मुझे पता है, केवल inline और टेम्पलेट फ़ंक्शंस हेडर फ़ाइलों में परिभाषित किया जा सकता है।

    static फ़ंक्शंस बहिष्कृत किए गए हैं, और एक अनाम नामस्थान में परिभाषित फ़ंक्शंस का उपयोग इसके बजाय किया जाना चाहिए (7.3.1.1 पी 2 देखें)। जब आप किसी हेडर में एक अनाम नामस्थान में फ़ंक्शन को परिभाषित करते हैं, तो उस शीर्षलेख (प्रत्यक्ष या परोक्ष रूप से) सहित प्रत्येक स्रोत कोड में एक अनूठी परिभाषा होगी (7.3.1.1 पी 1 देखें)। इसलिए, फ़ंक्शंस को हेडर फ़ाइलों में नामित नेमस्पेस में परिभाषित नहीं किया जाना चाहिए (केवल स्रोत फ़ाइलों में)।

    मानक संदर्भ सी ++ 03 मानक से हैं।

    संपादित करें:

    अगला उदाहरण दर्शाता है क्यों कार्य करता है और चर हेडर में अज्ञात नाम स्थान में परिभाषित किया जाना चाहिए:

    ops.hpp शामिल हैं:

    #ifndef OPS_HPP 
    #define OPS_HPP 
    namespace 
    { 
    int a; 
    } 
    #endif 
    

    DK1 .एचपीपी में शामिल हैं:

    #ifndef DK1_HPP 
    #define DK1_HPP 
    void setValue(); 
    void printValue(); 
    #endif 
    

    dk1.cpp शामिल हैं:

    #include "dk1.hpp" 
    #include "ops.hpp" 
    #include <iostream> 
    
    void setValue() 
    { 
        a=5; 
    } 
    void printValue() 
    { 
        std::cout<<a<<std::endl; 
    } 
    

    dk।सीपीपी शामिल हैं:

    #include "dk1.hpp" 
    #include "ops.hpp" 
    #include <iostream> 
    
    int main() 
    { 
        // set and print a 
        setValue(); 
        printValue(); 
    
        // set and print it again 
        a = 22; 
        std::cout<<a<<std::endl; 
    
        // print it again 
        printValue(); 
    } 
    

    संकलित इस तरह:

    g++ -ansi -pedantic -Wall -Wextra dk.cpp dk1.cpp 
    

    और आउटपुट:

    5 
    22 
    5 
    

    ऑप्स चर a स्रोत फ़ाइल dk1.cpp और dk.cpp

    +0

    हेडर में फ़ंक्शन परिभाषाओं के साथ अनाम नामस्थान होने के साथ कुछ भी गलत नहीं है - यह ओडीआर – Flexo

    +0

    'स्थिर' फ़ंक्शंस का उल्लंघन नहीं किया गया है, केवल 'स्थैतिक' ऑब्जेक्ट्स (सी ++ 11 से पहले)। –

    +1

    @awoodland: कंपाइलर के दृष्टिकोण से स्वाभाविक रूप से गलत कुछ भी नहीं है, लेकिन शायद प्रोग्राम के दृष्टिकोण से कहीं अधिक है। ऐसा लगता है कि ** एक ** हेडर में एक फ़ंक्शन वास्तव में ** ** विभिन्न अनुवाद इकाइयों में कई ** फ़ंक्शंस है, यह अतिरिक्त कोड (बड़े बाइनरी, निर्देश कैश का खराब प्रदर्शन) उत्पन्न करेगा, और यदि फ़ंक्शन में * स्थानीय स्थिर है * चर, प्रत्येक अनुवाद इकाई इसका स्वयं का संस्करण देखेंगे। संकलक ऐसा करेगा और खुश रहेंगे। लेकिन जो भी भविष्य में इसे डीबग करने की जरूरत है वह बहुत खुश नहीं होगा। –

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