खोज…


बहुविध रूप से परिभाषित कार्य

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

foo.h :

#ifndef FOO_H
#define FOO_H
#include <iostream>
void foo() { std::cout << "foo"; }
void bar();
#endif

foo.cpp :

#include "foo.h"
void bar() { std:: cout << "bar"; }

main.cpp :

#include "foo.h"
int main() {
    foo();
    bar();
}

इस कार्यक्रम में, समारोह foo शीर्षक में परिभाषित किया गया है foo.h है, जो दो बार शामिल किया गया है: एक बार से foo.cpp और से एक बार main.cpp । प्रत्येक अनुवाद इकाई में foo की अपनी परिभाषा समाहित है। ध्यान दें कि में गार्ड शामिल foo.h ऐसा होने से रोकने नहीं है, के बाद से foo.cpp और main.cpp दोनों को अलग-अलग foo.h । इस कार्यक्रम को बनाने की कोशिश करने का सबसे संभावित परिणाम एक लिंक-टाइम त्रुटि है जो कि foo को पहचानने में त्रुटि के रूप में परिभाषित किया गया है।

ऐसी त्रुटियों से बचने के लिए, किसी को हेडर में फ़ंक्शन की घोषणा करनी चाहिए और उन्हें इसी .cpp फ़ाइलों में परिभाषित करना चाहिए, कुछ अपवादों के साथ (अन्य उदाहरण देखें)।

इनलाइन कार्य

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

कार्यक्रम ऐसे व्यवहार करेगा जैसे कि फ़ंक्शन की एकल परिभाषा है।

foo.h :

#ifndef FOO_H
#define FOO_H
#include <iostream>
inline void foo() { std::cout << "foo"; }
void bar();
#endif

foo.cpp :

#include "foo.h"
void bar() {
    // more complicated definition
}

main.cpp :

#include "foo.h"
int main() {
    foo();
    bar();
}

इस उदाहरण में, हेडर फ़ाइल में सरल फ़ंक्शन foo को इनलाइन परिभाषित किया गया है जबकि अधिक जटिल फ़ंक्शन bar इनलाइन नहीं है और कार्यान्वयन फ़ाइल में परिभाषित किया गया है। दोनों foo.cpp और main.cpp अनुवाद इकाइयों की परिभाषा को शामिल foo , लेकिन इस कार्यक्रम अच्छी तरह से गठित के बाद से है foo इनलाइन है।

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

// in foo.h
class Foo {
    void bar() { std::cout << "bar"; }
    void baz();
};

// in foo.cpp
void Foo::baz() {
   // definition
}

समारोह Foo::baz , आउट-ऑफ-लाइन परिभाषित किया गया है, तो यह एक इनलाइन समारोह नहीं है, और हेडर में निर्धारित नहीं किया जाना चाहिए।

ओवरलोड रिज़ॉल्यूशन के माध्यम से ओडीआर उल्लंघन

इनलाइन फ़ंक्शंस के लिए समान टोकन के साथ भी, ODR का उल्लंघन किया जा सकता है यदि नामों की खोज एक ही इकाई को संदर्भित नहीं करती है। के विचार करते हैं func निम्नलिखित में:

  • header.h

    void overloaded(int);
    inline void func() { overloaded('*'); }
    
  • foo.cpp

    #include "header.h"
    
    void foo()
    {
        func(); // `overloaded` refers to `void overloaded(int)`
    }
    
  • bar.cpp

    void overloaded(char); // can come from other include
    #include "header.h"
    
    void bar()
    {
        func(); // `overloaded` refers to `void overloaded(char)`
    }
    

हमारे पास ओडीआर उल्लंघन है क्योंकि अनुवाद इकाई के आधार पर विभिन्न संस्थाओं को overloaded जाता है।



Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow