2012-12-29 21 views
7

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

अब मेरे प्रश्न पर: मैं सी ++ कक्षाओं के साथ ऐसा कैसे कर सकता हूं?

चलो कहते हैं कि मैं एक हेडर फाइल करते हैं:

class A { 
    int private_field; 
    int private_function(); 
public: 
    int public_function(); 
}; 

और मेरे .cpp फ़ाइल:

#include <iostream> 
#include "A.h" 

int A::private_function() { 
    std::cin >> private_field; 
    return private_field; 
} 

int A::public_function() { 
    return private_function() + 4; 
} 

जिसके परिणामस्वरूप वस्तु फ़ाइल में private_function एक अलग प्रतीक के रूप में छोड़ दिया जाता है, और public_function private_function कॉल (रेखांकित नहीं)। मैं निजी_फंक्शन आंतरिक लिंकेज देना चाहता हूं, इसलिए संकलक वही ऑप्टिमाइज़ेशन कर सकता है जब मैं सी का उपयोग करता हूं, मैंने अनाम नामस्थान और स्थैतिक के साथ प्रयास किया है, लेकिन मैं इसे काम करने के लिए प्राप्त नहीं कर सकता। इसे सही तरीके से कैसे करें, क्या यह भी संभव है? मैं जीसीसी का उपयोग करता हूं।

+1

"मैंने अनाम नामस्थान और स्थैतिक के साथ प्रयास किया है, लेकिन मैं इसे काम करने के लिए नहीं कर सकता क्योंकि मैं चाहूंगा।" क्या गलत हुआ? –

+0

मैंने आपके प्रश्न का उत्तर दिया है, लेकिन संकलक ऐसा करने के लिए आंतरिक संबंधों की आवश्यकता के बारे में अधिक अनुकूलन करने में सक्षम होना चाहिए। –

+0

इनलाइनिंग कभी-कभी (छोटे कार्यों के लिए) की जाती है, लेकिन मूल हमेशा बाएं => बड़े लाइब्रेरी आकार को छोड़ दिया जाता है। – Emil

उत्तर

8

कक्षा के सदस्यों के पास कभी भी आंतरिक संबंध नहीं है। मानक कहता है (धारा 9.3):

नामस्थान क्षेत्र में एक वर्ग के सदस्य कार्यों में बाहरी संबंध है। स्थानीय वर्ग के सदस्य कार्यों में कोई संबंध नहीं है।

तो यदि आप आंतरिक संबंध के साथ सहायक कार्यों को बनाना चाहते हैं, तो आपको एक गैर-सदस्य का उपयोग करना होगा।

static int private_function(A* pThis); 

class A 
{ 
    int private_field; 
    friend int private_function(A* pThis); 
public: 
    int public_function(); 
}; 

और फिर

#include <iostream> 
#include "A.h" 

static int private_function(A* pThis) 
{ 
    std::cin >> pThis->private_field; 
    return private_field; 
} 

int A::public_function() { 
    return private_function(this) + 4; 
} 

कृपया मानक (अनुभाग 11.3) से इस नियम पर ध्यान दें:

पहले में एक दोस्त घोषणा घोषित एक समारोह बाहरी संबंध है। अन्यथा, फ़ंक्शन अपने पिछले लिंक को बरकरार रखता है।

+2

मुझे लगता है कि मानक अजीब है। जब आप कोई दोस्त नहीं हैं, तो आप निजी कार्यों के लिए बाहरी संबंध क्यों पसंद करेंगे? – Emil

+6

@Emil: क्योंकि इससे अन्य अनुवाद इकाइयों में सार्वजनिक सदस्यों को रेखांकित करने की अनुमति मिलती है। इस बात पर विचार करें कि कक्षा में 'ए :: public_function' को इनलाइन घोषित किया गया था या नहीं। यह छोटा है, इसलिए संकलक सभी कॉल साइटों पर इनलाइन करना चाहते हैं, जो भी अनुवाद इकाई वे दिखाई देते हैं।लेकिन फिर उन सभी साइटों पर 'private_function' को जोड़ने योग्य होना चाहिए। –

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