2012-07-10 17 views
18

तक पहुंचने वाले आंतरिक वर्ग मैं सी ++ के लिए अपेक्षाकृत नया हूं, और मैंने इस चीज़ के उत्तर के लिए बहुत कुछ देखा है लेकिन मुझे कभी भी संतोषजनक उत्तर नहीं मिला।बाहरी वर्ग

मान लें कि मेरे पास FSM नामक एक संरचना है। आखिर में मेरे कोड में, FSM के कई उदाहरण बनाए जा सकते हैं। FSM की विशेषता int X है जो स्थिर नहीं है, FSM के प्रत्येक उदाहरण के पास X का अपना मान होना चाहिए।

Error: 'FSM::getX' : illegal call of non-static member function

मेरा प्रश्न है:

struct FSM 
{ 
    public: 
    int x; 

    int getX(){return x;} 

    struct submachine 
    { 
     void onentry() {int g = getX();}; 
    }; 
}; 

यह निम्न त्रुटि देता है:

अब, FSM की विशेषताओं में से एक एक और संरचना submachine जो इस तरह X का मूल्य को पढ़ने के लिए की जरूरत है , submachineFSM का सदस्य है, तो क्या इसे FSM के सभी विशेषताओं के स्थानीय उदाहरणों तक पहुंच नहीं है? और यदि नहीं, तो जब हम FSM का उदाहरण बनाते हैं, तो क्या हम अपने सभी सदस्यों का उदाहरण नहीं बनायेंगे i.e. submachine? और यदि ऐसा है, तो हमें onentry() की आवश्यकता वाले ऑब्जेक्ट को बनाने की आवश्यकता क्यों है?

मुझे लगता है कि संकलक सही है, इसलिए मैं यह जानना चाहूंगा कि यह काम करने का कोई तरीका है या नहीं।

नोट: दुर्भाग्यवश, आंतरिक संरचनाओं के उदाहरण (submachine) तत्काल होते हैं जब कोई ईवेंट कहा जाता है और इस प्रकार मैं केवल प्रकार को परिभाषित कर सकता हूं, और FSM में उनके लिए वस्तुओं को तत्काल नहीं कर सकता।

उत्तर

34

my question is, submachine is a member of FSM, so it should have access to local instances of all the attributes of FSM, no?

नहीं जावा में विपरीत, आंतरिक वर्ग वस्तुओं के बाहरी ऑब्जेक्ट का निहित संदर्भ नहीं है।

wouldn't we be creating an intance of all its members i.e. submachine?

submachine एक प्रकार, नहीं एक सदस्य चर रहा है। आप एक सदस्य चर चाहता था, तो आप इस तरह कुछ करने के लिए चाहते हैं:

struct FSM { 
    struct submachine { 
     ... 
    }; 

    submachine sm; // Member variable of type submchine 
}; 

और अगर आप sm चाहते हैं कि अपनी मूल वस्तु "देख", आप इसे स्पष्ट रूप से उत्तीर्ण होना होगा:

struct FSM { 
    struct submachine { 
     FSM &parent; // Reference to parent 
     submachine(FSM &f) : parent(f) {} // Initialise reference in constructor 
    }; 

    submachine sm; 

    FSM() : sm(*this) {} // Pass reference to ourself when initialising sm 
}; 

ध्यान दें कि एक ही सिद्धांत submachine के उदाहरणों के लिए लागू होता है जो सदस्य चर नहीं हैं। यदि आप चाहते हैं कि वे FSM उदाहरण तक पहुंच सकें, तो आपको एक संदर्भ पारित करना होगा।

ध्यान दें कि आप एक संदर्भ के बजाय एक सूचक का उपयोग कर सकते हैं। वास्तव में, एक सूचक कई मामलों में अधिक लचीलापन प्रदान करता है।

+0

यदि कोई तरीका है जो मैं पूरा करना चाहता हूं जो मैं पूरा करना चाहता हूं? – Kam

+2

डाउनवॉटर: साझा करने की देखभाल? –

+0

(देरी के लिए खेद है, लिंक ढूंढ रहा था)। नेस्टेड कक्षाएं सदस्य हैं और बाहरी वर्ग तक किसी अन्य सदस्य की तरह पहुंच सकते हैं, [डीआर 45] (http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#45) का हिस्सा 2003 –

2

नोट करें कि struct submachine घोषित करना केवल प्रकार को परिभाषित करता है; यह वास्तव में उस प्रकार की कक्षा में एक फ़ील्ड नहीं बनाता है।

आप निम्न में से एक की आवश्यकता होगी:

struct submachine mysub; // creates a field after the class is defined 

या

struct submachine 
{ 
    . . . 
} mysub; // creates the field "mysub" also, as the structure is being defined 

यह mysub क्षेत्र में आता है, और आप तो एक ही तरीका है कि आप x का उपयोग करता हूँ में इसे का उपयोग।

submachine की परिभाषा (यह प्रारंभ करने में जैसे एक सूचक क्षेत्र FSM*, और शायद submachine(FSM* fsm): fsm_(fsm) {} की तरह एक निर्माता) ताकि आप एक निश्चित X मूल्य का उपयोग करने की fsm_->getX() कह सकते हैं एक विशिष्ट FSM शामिल करने के लिए की जरूरत है।

+0

दुर्भाग्य से, आंतरिक संरचनाओं के उदाहरण रनटाइम (घटनाओं) घोषित किए जाते हैं और इस प्रकार मैं केवल प्रकार को परिभाषित कर सकता हूं, और उनके लिए वस्तुओं को कम नहीं कर सकता। – Kam

+2

आप अभी भी 'int g = getX();' FSM' ऑब्जेक्ट के बिना नहीं कर सकते हैं। यह सवाल का जवाब कैसे देता है? –

1

मैं केवल कि आप क्या करना चाहते हैं पर एक अनुमान बनाने रहा हूँ, लेकिन अगर मेरा अनुमान सही है, तो आप नीचे दिए गए की तरह कुछ के बारे में सोच हो सकती है।

struct FSM_Base { 
    int x; 

    struct submachine1; 
    struct submachine2; 

    FSM_Base() : x(0) {} 
    virtual ~FSM_Base() {} 
}; 

struct FSM_Base::submachine1 : virtual public FSM_Base { 
    void oneentry() { int g = x; } 
}; 

struct FSM_Base::submachine2 : virtual public FSM_Base { 
    void oneentry() { int g = x; } 
}; 

struct FSM : public FSM_Base::submachine1, 
      public FSM_Base::submachine2 { 
    FSM_Base::submachine1 * sub1() { return this; } 
    FSM_Base::submachine2 * sub2() { return this; } 
}; 
3

विचार है कि अपने उदाहरण में, मैं कानूनी तौर पर एक नि: शुल्क समारोह

void foo() 
{ 
    FSM::submachine sub; 
    sub.onentry(); 
} 

लिख सकते हैं जहां कोई FSM उदाहरण है कि sub का उल्लेख कर सकते हैं।

या तो, के रूप में ओली कहते हैं, अपनी मूल FSM वस्तु को submachine वस्तु की दुकान के लिए एक संदर्भ है, या शायद सिर्फ (यह स्पष्ट नहीं है कि यह कैसे लागू किया जाता है) सीधे onentry में x का मूल्य गुजरती हैं।


Boost.MSM docs का शीघ्रता से अवलोकन से मैं non-default-constructed submachines पर इस नोट मिल गया।

यह बहुत बदसूरत है, मैं इसे पीछे छोड़ने के लिए पर्याप्त बैकएंड को समझ नहीं पा रहा हूं, और शाब्दिक कोड पेस्टिंग के लायक होने के अलगाव में पर्याप्त समझ नहीं पाएगा।

template <class Event,class FSM> void on_entry(Event const&,FSM&); 

है कि अगर सही है, आप या तो एक सूचक अपने बाहरी राज्य मशीन on_entry को स्टोर कर सकते हैं, या का मान निकालने:

वहाँ भी से जुड़ा हुआ उदाहरण कोड निम्न हस्ताक्षर के साथ टामी के प्रवेश विधि से पता चलता वहां एक्स और सबमिशन में इसे रिकॉर्ड करें।

+0

धन्यवाद! यही वह है जिसे मैं ढूंढ रहा था, अब मैं वास्तव में इसे प्राप्त करता हूं। ओएलआई के पद के साथ इस पोस्ट ने इसे मेरे लिए बनाया है। काश मैं दोनों उत्तरों को स्वीकार कर सकता हूं। – Kam

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