2016-02-25 11 views
5
// SomeOtherClass.hpp 
#pragma once 

int someOtherCallMe(); 

class SomeOtherClass { 
    public: 

    static int callMe() { 
     static int _instance = 7; 
     ++_instance; 
     return _instance; 
    } 
}; 


// SomeOtherClass.cpp 
#include "SomeOtherClass.hpp" 

int 
someOtherCallMe() { 
    return SomeOtherClass::callMe(); 
} 

// main.cpp 

#include "SomeOtherClass.hpp" 

#include <iostream> 

int 
main() { 

    std::cout << SomeOtherClass::callMe(); 
    std::cout << someOtherCallMe(); 

    return 0; 
} 

मेरे पास तीन फ़ाइलें हैं: SomeOtherClass.hpp/cpp, main.cpp। उन फ़ाइलों के परिणामस्वरूप दो द्विआधारी: साझा लाइब्रेरी (SomeOtherClass.cpp का) और निष्पादन योग्य (main.cpp का, साझा लाइब्रेरी से जुड़ा हुआ)।सी ++ हेडर में परिभाषित स्थिर वर्ग विधियों में सी ++ स्थिर चर

क्या सी ++ गारंटी देता है कि static <any-type> _instance किसी प्रोग्राम के निष्पादन के दौरान एक ही चर होगा (इससे कोई फर्क नहीं पड़ता कि कितनी द्विआधारी परिभाषित की गई थी)?

नोट स्थिति को स्पष्ट करने के लिए। इस परिस्थिति में मुझे जो भ्रम दिखाई देता है वह यह है कि, एक तरफ, SomeOtherClass::callMe प्रोग्राम में दो बार परिभाषित किया गया है, इसकी अपेक्षा की जाती है (क्योंकि क्लास स्टेटिक सदस्य फ़ंक्शन वास्तव में आंतरिक लिंकेज के साथ एक नियमित कार्य होता है, अगर उन्हें स्थान पर परिभाषित किया जाता है, तो इसमें मामला), और यही वह है जिसे आप अलग-अलग हिस्सों से देख सकते हैं। चूंकि हमारे पास मशीन कोड में स्थैतिक स्थानीय चर के साथ दो कार्य हैं। भाषा/मानक उनके व्यवहार को कैसे योग्य बनाता है?

+0

एमएस विजुअल स्टूडियो का उपयोग करते समय, आपको डीएलएल बनाने और काम करने के लिए डीएलएल का उपयोग करते समय सही '__declspec' का उपयोग करना होगा। –

+0

हां, मुझे इसके लिए धन्यवाद पता है। – user14416

+0

यदि प्रश्न वास्तव में डीएलएल सीमाओं में स्थिर चर के बारे में है तो शीर्षक में उल्लेख किया जाना चाहिए और टेक्स्ट –

उत्तर

0

हां। एक स्थिर एक एकल मूल्य होगा। कई अन्य चीजें अच्छी तरह से परिभाषित नहीं हैं या मानक के लिए नए हैं। (वे वैश्विक रूप से कब शुरू होते हैं? क्या फ़ंक्शन थ्रेड-सुरक्षित के भीतर स्थैतिक प्रारंभिकरण का कोड है?) लेकिन, हाँ, आप केवल एक होने पर भरोसा कर सकते हैं। आप नहीं स्थिर (निजी तौर पर) अपने सी ++ वर्ग पुस्तकालय साझा लाइब्रेरी में लिंक कर सकते हैं:

यहाँ केवल स्पष्टीकरण आप एक साझा पुस्तकालय (.so या .dll) बना रहे हैं तो मानक के बाहर लेकिन व्यावहारिक महत्व का है। अन्यथा, यदि आप दो अलग साझा पुस्तकालयों में ऐसा करते हैं तो यह दो प्रतियां बनायेगा। (यह टिप्पणी लाइब्रेरी के बारे में सबकुछ पर लागू होती है, न केवल स्थैतिक चर। यदि आप ऐसा करते हैं, तो सब कुछ का दोहराव है।)

संपादित करें: कई प्लेटफॉर्म (जैसे कि लिनक्स और विंडोज) पर इसका उपयोग किया जा सकता है उद्देश्य से अपने स्थैतिक चर "छुपाएं"। यदि आप अपने कार्य/वर्ग को डीएलएल/एस के बाहर सुलभ नहीं करते हैं (declspec या दृश्यता विशेषता का उपयोग करके), तो आप सुनिश्चित कर सकते हैं कि आपकी डीएलएल की पूरी कक्षा की अपनी प्रति है। यह तकनीक पुस्तकालयों के बीच अवांछित बातचीत को कम करने में मदद कर सकती है। हालांकि, आपके मामले में, ऐसा लगता है कि आप वास्तव में केवल एक चाहते हैं, जो होगा यदि आपकी कक्षा में आपके सभी पुस्तकालयों में उचित दृश्यता है (केवल एक में दिखाई दे रही है, और अन्य पुस्तकालय उस पुस्तकालय से लिंक हैं)। बाहरी लिंकेज के साथ एक समारोह एक अनुवाद इकाई में इनलाइन घोषित किया जाता है, तो यह है, जिसमें यह प्रतीत होता है सब अनुवाद इकाइयों में इनलाइन घोषित किया जाएगा

संपादित करें पर दोबारा मानक

का उल्लेख करने के लिए; कोई निदान की आवश्यकता नहीं है। बाहरी लिंकेज के साथ एक इनलाइन फ़ंक्शन में सभी अनुवाद इकाइयों में एक ही पता होगा। एक बाहरी इनलाइन फ़ंक्शन में एक स्थिर स्थानीय चर हमेशा एक ही ऑब्जेक्ट को संदर्भित करता है।

7.1.2.4, सी ++ 14

+0

में अधिक प्रमुख रूप से उल्लेख किया जाना चाहिए, यह क्यों कम हो गया है? – user14416

+0

प्रिय रॉब, इस प्रयास के लिए धन्यवाद, आपका जवाब अब जो कुछ मैं चाहता था उसके सबसे नज़दीक प्रतीत होता है, मुझे सच में पता नहीं है कि आप क्यों नीचे गए थे, एमबी आपने शुरुआत में अजीब लिखा था, मैंने एक नज़र नहीं ली वास्तव में परिवर्तन इतिहास में, या एमबी यह सिर्फ मैला stackoverflow पाठक है जो भी हो। यदि आप मानक और/या कुछ जोरदार संसाधनों के लिए कुछ संदर्भ दे सकते हैं, और किस तरह का जुड़ाव है, और मानक/भाषा इस प्रकार की संरचनाओं को कैसे अर्हता प्राप्त करती है, तो मैं इसकी बहुत सराहना करता हूं .. – user14416

+0

मुझे लगता है कि मैंने मतदान किया क्योंकि यह एक जटिल विषय है जो हां/नहीं के साथ जवाब देना बहुत मुश्किल है। मैंने डाउनवॉट किए जाने के बाद स्पष्टीकरण भी जोड़ा। मुझे नहीं लगता कि डीएलएस और साझा बाइनरी को कवर करने के लिए मानक में कुछ भी है। जानकारी एक परियोजना लीड (मुझे) से है, जिसे दर्जनों डीएल और कई डेवलपर्स के साथ एक उत्पाद का प्रबंधन करना है। हमने इन सभी गलतियों से बनाया और सीखा है। निचली पंक्ति: यदि इसे साझा किया जाता है, इसे कहीं और परिभाषित करें, इसे सही निर्यात करें, और संकलक बाकी की देखभाल करता है। –

1

Does C++ guaranties that static _instance will be a single variable during the execution of a program (does not matter in how many binaries it was defined)?

मुझे नहीं लगता कि कुछ भी है कि भाषा के बारे में क्या कहना है है। यह स्थैतिक पुस्तकालयों या गतिशील पुस्तकालयों के बारे में बात नहीं करता है।

यह सुनिश्चित करने के लिए तंत्र प्रदान करने के लिए एक कार्यान्वयन की ज़िम्मेदारी है कि एक परिभाषा संभव हो। यह सुनिश्चित करने के लिए उपयोगकर्ता पर निर्भर करता है कि वे कार्यान्वयन द्वारा प्रदत्त तंत्र का उपयोग करें, जिसमें फ़ंक्शन में static चर की एक परिभाषा है।

+0

मैं आपसे सहमत हूँ कि यह उपयोगकर्ता के लिए जो चुनता है यह क्या चाहता है और भाषा के माध्यम से यह करता है । लेकिन इस स्थिति में मैं कहूंगा कि स्थैतिक कार्य ('SomeOtherClass :: callMe') कोड में डुप्लिकेट किया गया है। स्थैतिक चर से भी डुप्लिकेट किया जाना चाहिए, लेकिन यह कम से कम g ++ के साथ नहीं है। लेकिन दूसरी तरफ, इसे डुप्लिकेट नहीं किया जाना चाहिए क्योंकि भाषा कहती है कि 'स्थिर' एकल वस्तु की गारंटी देता है। – user14416

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