2010-06-17 10 views
10

जबकि मैं this question के स्वीकृत उत्तर को पढ़ रहा था, मेरे पास निम्न प्रश्न था:"केवल एक कार्यान्वयन" नियम का अपवाद?

आमतौर पर, शीर्षलेख फ़ाइलों (.hpp या जो कुछ भी) में विधियों को परिभाषित किया जाता है, और स्रोत फ़ाइलों में कार्यान्वयन (.cpp या जो भी हो)।

कभी भी "स्रोत फ़ाइल" (#include <source_file.cpp>) को शामिल करने के लिए खराब प्रथाओं में से एक मुख्य कारण यह है कि इसके तरीकों के कार्यान्वयन को डुप्लिकेट किया जाएगा, जिसके परिणामस्वरूप त्रुटियों को जोड़ दिया जाएगा।

जब कोई लिखता है:

#ifndef BRITNEYSPEARS_HPP 
#define BRITNEYSPEARS_HPP 

class BritneySpears 
{ 
    public: 

    BritneySpears() {}; // Here the constructor has implementation. 
}; 

#endif /* BRITNEYSPEARS_HPP */ 

वह कन्स्ट्रक्टर के कार्यान्वयन (यहां एक "खाली" कार्यान्वयन, लेकिन अभी भी) दे रहा है।

लेकिन फिर इस हेडर फ़ाइल को कई बार (विभिन्न स्रोत फ़ाइलों पर उर्फ) सहित क्यों लिंक समय पर "डुप्लिकेट परिभाषा" त्रुटि उत्पन्न नहीं करेगा?

+0

इनलाइन और एक परिभाषा नियम के बारे में एक और जवाब यहां दिया गया है: http://stackoverflow.com/questions/908830/isnt-cs-inline-totally-optional/910686#910686 –

+2

बीटीडब्ल्यू, ब्रिटनीस्पीर्स के आपके कोड में कमजोर संबंध है। वास्तविक जीवन की तरह :) –

+1

अकेले ब्रिटनी छोड़ें –

उत्तर

13

इनलाइन फ़ंक्शंस "एक परिभाषा नियम" के अपवाद हैं: आपको एक से अधिक संकलन इकाई में उनके समान कार्यान्वयन की अनुमति है। कार्य इनलाइन हैं यदि उन्हें inline घोषित किया गया है या कक्षा परिभाषा के अंदर लागू किया गया है।

+0

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

+1

@nikie: भले ही वहां एक कॉल निर्देश हो, फिर भी लिंकर द्वारा कार्यों का अलग-अलग व्यवहार किया जाता है, विवरण के लिए मेरे उत्तर में लिंक देखें। – sharptooth

+3

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

2

क्योंकि यह एक "इनलाइन" फ़ंक्शन है। इनलाइन फ़ंक्शंस को हेडर से जितनी बार चाहें उतनी बार शामिल किया जा सकता है और वे डुप्लिकेट परिभाषा लिंकर त्रुटियों का कारण नहीं बनते हैं।

कंपाइलर उन्हें इनलाइन लाने की भी कोशिश करेगा, इसलिए ऊपर दिए गए उदाहरण में, कंपाइलर आज़माएं और पूरी तरह से कन्स्ट्रक्टर को कॉल को खत्म कर देगा।

7

कक्षा परिभाषा के अंदर कार्यान्वयन के साथ सदस्य कार्य इनलाइन कार्यों के रूप में माना जाता है। इनलाइन फ़ंक्शंस को एक परिभाषा नियम से मुक्त किया जाता है।

विशेष रूप से जब लिंकर एक ही हस्ताक्षर के साथ दो इनलाइन फ़ंक्शंस देखता है तो यह उनका व्यवहार करता है जैसे कि यह वही कार्य है और बस उनमें से एक चुनता है। यह to really weird hard to detect problems का नेतृत्व कर सकता है।

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