2011-05-28 10 views
24

स्पष्ट रूप से टेम्पलेट पुस्तकालयों को केवल शीर्षलेख होना चाहिए, लेकिन गैर-टेम्पलेट्स के लिए, आपको चीजों को केवल हेडर बनाने के लिए कब करना चाहिए?मुझे लाइब्रेरी हेडर बनाने पर विचार कब करना चाहिए?

+2

जब आप अपने आईपी को उजागर नहीं करते हैं। – Nim

+0

@Nim: यह बूस्ट सॉफ्टवेयर लाइसेंस के तहत एक ओपन-सोर्स प्रोग्राम है, इसलिए मुझे निश्चित रूप से कोई फर्क नहीं पड़ता। :) –

+0

@ बिली: ओह, आप बूस्ट में गए? Gratz? : पी – Xeo

उत्तर

14

यदि आपको लगता है कि आपकी गैर-टेम्पलेट लाइब्रेरी केवल हेडर हो सकती है, तो इसे दो फ़ाइलों में विभाजित करने पर विचार करें, फिर एक तीसरी फ़ाइल प्रदान करें जिसमें .h और .cpp (एक गार्ड शामिल है) शामिल हैं।

तब कोई भी जो आपके पुस्तकालय का उपयोग कई अलग-अलग टीयू में करता है, और संदेह करता है कि यह बहुत संकलन समय खर्च कर सकता है, आसानी से इसका परीक्षण करने के लिए परिवर्तन कर सकता है।

एक बार जब आप जानते हैं कि उपयोगकर्ताओं के पास लाइब्रेरी का उपयोग करने का विकल्प है, तो उत्तर शायद "जब भी संभव हो तो वह विकल्प प्रदान करें" बन जाता है। इतने सारे समय में कि कई टीयू से इसे शामिल करने से ओडीआर का उल्लंघन नहीं होगा। उदाहरण के लिए, यदि आपके गैर- static नि: शुल्क फ़ंक्शंस static ग्लोबल्स का संदर्भ लेते हैं, तो आप भाग्य से बाहर हैं, क्योंकि विभिन्न टीयू में उस फ़ंक्शन की विभिन्न परिभाषाएं उसी नाम से अलग-अलग ऑब्जेक्ट्स का संदर्भ लेंगी, जो एक ओडीआर-उल्लंघन है।

+2

ओह। इस तरह से ऐसा करने के बारे में कभी सोचा नहीं। +1 '.cpp' '# शामिल' होने पर फ़ंक्शन घोषणाओं को 'इनलाइन' पर सही तरीके से सेट करने के लिए कैसे मिलता है? –

+2

@ बिली: तीसरी फ़ाइल (दूसरा। एच) में '# परिभाषित करें 'सेट करें, और .cpp में' #ifdef _____ # परिभाषित करें DO_INLINE इनलाइन #else # परिभाषित करें DO_INLINE # endif'। – Xeo

+1

या उन्हें हमेशा 'इनलाइन' चिह्नित करें, यह कोई नुकसान नहीं करता है। –

-2

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

दूसरे शब्दों में, हेडर में परिभाषा डालना एक बहुत बुरा विचार है। आपको केवल घोषणाओं और टेम्पलेट्स के साथ रहना चाहिए।

टेम्पलेट्स के लिए, कंपाइलर्स जानते हैं कि आप एक ही शीर्षलेख को एक से अधिक बार शामिल कर सकते हैं, वे एक ही कोड को बार-बार उत्पन्न नहीं करेंगे।

संपादित करें: यदि आपका मतलब है "सब कुछ रेखांकित रखें", मुझे लगता है कि यह एक बहुत ही खराब दृष्टिकोण है। हेडर फाइल पूरी तरह से अपठनीय हो जाती है, और कार्यान्वयन में कोई भी बदलाव आपकी लाइब्रेरी के किसी भी उपयोगकर्ता को सबकुछ पुनः संयोजित करने के लिए मजबूर करता है।

+0

-1: यह सच नहीं है। जब तक उनके पास आंतरिक संबंध होता है तब तक आप शीर्षकों में परिभाषाएं डाल सकते हैं। (उदाहरण के लिए उन्हें 'इनलाइन' घोषित किया गया है) –

+0

'इनलाइन'। 'निफ ने कहा। – Xeo

+0

कभी-कभी, प्रत्येक परिवर्तन के लिए पुन: संकलित करने की आवश्यकता ऐसी सीमा नहीं होती है। –

0

टेम्पलेट पुस्तकालयों को केवल हेडर होने की आवश्यकता नहीं है: कार्यान्वयन में टेम्पलेट पैरामीटर से स्वतंत्र कुछ टुकड़े हो सकते हैं, और कुछ कारणों से (जैसे कम कोड आकार) विशेष बाइनरी में अलग हो जाते हैं।

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

+0

एलेक्सी: मुझे एसटीएल की एक लाइब्रेरी दिखाएं जो ** ** ** हेडर-केवल नहीं है। और एसटीएल के साथ, मेरा मतलब कंटेनर/एल्गोरिदम/इटरेटर भाग है, पूरी मानक लाइब्रेरी नहीं। – Xeo

+0

शायद, लेकिन टेम्पलेट पुस्तकालयों के टेम्पलेट भागों केवल शीर्षलेख होना चाहिए। अनुवाद इकाई में एक टेम्पलेट परिभाषा मौजूद होने की आवश्यकता है ताकि संकलक इसे तुरंत चालू कर सके। कुछ एसटीएल में अधिकांशतः द्विआधारी भाग होते हैं क्योंकि या तो ए को सामान्य सी ++ रनटाइम के हिस्से के रूप में शामिल किया जाता है जिसमें टुकड़े टुकड़े नहीं होते हैं (उदा। 'Libstdcxx'), या बी। वे घटक होते हैं जो टेम्पलेट नहीं होते हैं। प्रदर्शन की बात के लिए, आजकल अधिकांश कंपाइलर्स में लिंक टाइम कोड पीढ़ी होती है जो रिलीज बिल्ड के लिए दोनों के बीच प्रदर्शन अंतर को काफी दूर करती है। –

+0

@Xeo: ठीक है, आप शायद सही हैं, एसटीएल भाषा समर्थन पुस्तकालय के समान नहीं है। –

3

आप Boost.Asio लीड का पालन कर सकते हैं।

वे पुस्तकालयों के दो संस्करण प्रदान करते हैं: हेडर-केवल और हेडर + लाइब्रेरी।

वे अपने शीर्षकों को शामिल करने से पहले परिभाषित (या नहीं) एक एकल मैक्रो के साथ करते हैं। मुझे लगता है कि डिफ़ॉल्ट (यदि परिभाषित नहीं किया गया है) हेडर-केवल संस्करण का उपयोग करना है।

Optional Separate Compilation देखें।

ध्यान दें कि वे कैसे एक ही स्रोत फ़ाइल को संकलित करने के लिए अच्छी तरह से प्रदान करते हैं जो गतिशील रूप से लोड की गई लाइब्रेरी के विरुद्ध सब कुछ या विकल्प को परिभाषित करने के विकल्प को परिभाषित करता है।

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