जब C में C नहीं होता है तो C + में आंतरिक जुड़ाव क्यों होता है?


83

विषय देखें। वे क्या सोच रहे थे?

अद्यतन: भ्रम को बचाने के लिए "स्थिर" से "आंतरिक लिंकेज" में परिवर्तित।

एक उदाहरण देने के लिए ... निम्नलिखित को एक फ़ाइल में रखना:

const int var_a = 1;
int var_b = 1;

... और g++ -c test.cppकेवल निर्यात के साथ संकलन var_b

जवाबों:


113

मेरा मानना ​​है कि आप का मतलब है

C ++ में आंतरिक लिंकेज को कम क्यों करता है

यह सच है कि अगर आप नेमस्पेस गुंजाइश पर एक कास्ट ऑब्जेक्ट घोषित करते हैं, तो इसका आंतरिक संबंध है।

परिशिष्ट C ( C ++ 11, C.1.2 ) तर्क देता है

परिवर्तन: फ़ाइल स्कोप का एक नाम जिसे स्पष्ट रूप से कास्ट घोषित किया गया है, और स्पष्ट रूप से बाहरी घोषित नहीं किया गया है, में आंतरिक लिंकेज है, जबकि सी में यह बाहरी लिंकेज होगा

Rationale: क्योंकि कॉस्ट ऑब्जेक्ट्स को C ++ में संकलित समय मानों के रूप में उपयोग किया जा सकता है, यह फीचर प्रोग्रामर से प्रत्येक कॉन्स्टेंट के लिए स्पष्ट इनिशलाइज़र मान प्रदान करने का आग्रह करता है। यह सुविधा उपयोगकर्ता को हेडर फ़ाइलों में कास्ट ऑब्जेक्ट डालने की अनुमति देती है जो कई संकलन इकाइयों में शामिल हैं।


ऐसा लगता है कि गैर-कॉस्ट ग्लोबल ऑब्जेक्ट्स को भी आरंभीकृत किया जा सकता है, लेकिन मानक इसे आंतरिक लिंकेज क्यों नहीं देते हैं?
योंग ली

13

जैसा कि लिट ने कहा, constवस्तुओं में C ++ में आंतरिक जुड़ाव होता है। इसका कारण यह है कि उनका उपयोग इस तरह किया जाना है:

// a.cpp
const int BUFSIZE = 100;
char abuf[BUFSIZE];

// b.cpp
const int BUFSIZE = 256
int bbuf[BUFSIZE];

6

कॉन्स्ट और स्टेटिक C और C ++ दोनों में ऑर्थोगोनल कॉन्सेप्ट हैं।

constकीवर्ड संकलक बताता है किसी भी अभिव्यक्ति की lvalue के रूप में प्रदर्शित होने से चर अस्वीकृत करने के लिए - अनिवार्य रूप से यह केवल पढ़ने के लिए बना रही है।

C में, staticकीवर्ड के उपयोग के आधार पर इसके कई उपयोग हैं। जब किसी फ़ंक्शन के वेरिएबल पर लागू किया जाता है, तो यह इंगित करता है कि वेरिएबल किसी फ़ंक्शन के स्थानीय दायरे में संग्रहीत नहीं है, लेकिन इसके इनवोकेशन पर पहुंच योग्य है। जब एक वैश्विक चर या फ़ंक्शन पर लागू किया जाता है, तो यह केवल एक विशेष फ़ाइल के लिए सुलभ हो जाता है - दूसरे शब्दों में, यह केवल संकलन इकाई (जब तक घोषित नहीं extern) के भीतर सुलभ है ।

C ++ में, staticकीवर्ड का उपयोग एक वर्ग परिभाषा के भीतर किया जा सकता है, प्रत्येक उदाहरण के लिए स्थानीय होने के बजाय, कक्षा के सभी उदाहरणों में साझा किए गए चर या कार्यों को करने के लिए। इसके अलावा, C ++ में एक स्थिर वर्ग फ़ंक्शन केवल उस वर्ग के स्थिर चर (या जिन कक्षाओं तक उसकी पहुंच है) तक पहुंच सकता है। अब, C ++ में constसदस्यों को संकलन इकाई में आंतरिक लिंकेज दिया जाता है जब तक कि उन्हें स्पष्ट रूप से घोषित नहीं किया जाता है extern- यह वह हो सकता है जो आप इसका उल्लेख कर रहे हैं। यह शीर्ष-समय स्थिरांक को हेडर फ़ाइलों के उपयोग के माध्यम से पूरे यूनिट में साझा करने की अनुमति देता है। हालांकि, ध्यान रखें कि सदस्य वास्तव में स्थिर नहीं हैं - बल्कि स्थिरांक को प्रत्येक स्थान पर संकलित किया जाता है, जहां इसे संदर्भित किया जाता है।


6

C & C ++ में स्थिर शब्द के कई अर्थ होते हैं (यह लिंकेज और स्टोरेज को नियंत्रित कर सकता है) आपको अपने तर्क की सराहना करने के लिए स्ट्रॉस्ट्रुप का D & E पढ़ना होगा - लेकिन जब आप एक वैरिएबल को नेमस्पेस स्कोप में कॉन्स्टेबल होने की घोषणा करते हैं, तो यह स्वचालित रूप से आंतरिक लिंकेज है - जबकि सी में आपको इसे आंतरिक लिंकेज के लिए मजबूर करने के लिए स्थिर घोषित करना होगा।

सी ++ में बेशक, लिंकेज को नियंत्रित करने के लिए स्थैतिक का उपयोग किया गया है, सी ++ में आंतरिक लिंकेज का अनुकरण करने के लिए अनाम नेमस्पेस का उपयोग किया जा सकता है।

C ++ में const वैरिएबल प्रीप्रोसेसर कॉन्स्टेंट को प्रतिस्थापित करने वाले थे - और चूंकि प्रीप्रोसेसर कॉन्सटेंट केवल उन्हीं फाइलों में दिखाई देते हैं जो उन्हें परिभाषित करते हैं, इसी तरह, कॉन्स्ट वैरिएबल स्वचालित रूप से केवल उस फाइल में दृश्यमान होता है जो इसे परिभाषित करता है।


4

वे अवधारणाएं रूढ़िवादी हैं और उन्हें एक ही चीज के रूप में नहीं सोचा जाना चाहिए।

कॉन्स्टेंस एक एक्सेस प्रॉपरिटी है: यह केवल तभी बताता है जब आपका वेरिएबल केवल-रीड (कॉन्स्ट) या राइट-रीड (नॉन-कॉन्स्ट) होना चाहिए।

स्थैतिकता एक जीवन-काल (और तकनीकी रूप से स्मृति स्थानीयकरण) गुण है: यह बताता है कि क्या चर वर्ग के दायरे में वैश्विक होगा (जब एक कक्षा में) या एक अनुवाद इकाई (जब एक सीपीपी में परिभाषित वैश्विक चर के साथ प्रयोग किया जाता है) ।


-2

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

class A {
public:
  A(int newx) : x(newx);
private
  int x;
}

litb सबसे अच्छा जवाब देता है, ऊपर।


वह हमेशा नहीं है? (
litb

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.