बूस्ट का उपयोग :: मॉडल राज्यों का वर्णन करने के लिए संस्करण

डेटा मॉडल में, कुछ स्विचिंग राज्यों को संग्रहीत करना बहुत बार आवश्यक होता है। C ++ में ऐसा करने का क्लासिक तरीका एनम एनम प्रकार का उपयोग करना है।



उदाहरण के लिए, यदि आपके प्रोग्राम में कोई उपयोगकर्ता दो स्क्रीन के बीच स्विच कर सकता है, तो आप enum स्क्रीन {screen_one, screen_two} शुरू करते हैं; और चर स्क्रीन cur_screen_। रेंडरर को मॉडल से "वर्तमान में चयनित स्क्रीन" प्राप्त करना होगा, और फिर इसे ड्रा करना चाहिए, जिससे विशेष रूप से इस स्क्रीन से संबंधित अतिरिक्त डेटा के लिए मॉडल पूछा जा सके। कुछ इस तरह:



switch (model.cur_screen())

{

case screen_one:

model.get_screen_one_elements();

...

case screen_two:

model.get_screen_two_elements();

...

}









इस मॉडल का उपयोग करके, प्रोग्रामर डेटा का अनुरोध कर सकता है जो वर्तमान स्थिति के लिए पूरी तरह अप्रासंगिक है। उदाहरण के लिए, दूसरी स्क्रीन के तत्वों की सूची प्राप्त करने के लिए get_screen_two_elements () विधि को कॉल करें जब वर्तमान स्क्रीन पहली हो। स्क्रीन-विशिष्ट विधियों में ASSERT अभिकथनों (cur_screen_ == screen_one) का उपयोग करना अच्छा है। यह कुछ रनटाइम नियंत्रण प्रदान करता है।



लेकिन संकलन :: समयबद्धता के साथ संकलन-समय नियंत्रण और अधिक स्पष्ट राज्य पृथक्करण प्रदान करने का एक तरीका है।





इस दृष्टिकोण के साथ, screen_one और screen_two एनम तत्व नहीं हैं, लेकिन पूर्ण कक्षाएं हैं। और इस राज्य पर निर्भर सभी डेटा और तरीके राज्य की श्रेणी में आते हैं।



मुख्य मॉडल में अब get_screen_one_elements () विधि नहीं है, अब screen_one वर्ग में एक get_elements () विधि है। वर्तमान में चयनित स्क्रीन को प्रकार के बढ़ावा के एक संस्करण में सहेजा गया है :: संस्करण <screen_one, screen_two>।



class screen_one

{

public :

const std :: vector < screen_one_elements >& get_elements() const

{

return ...;

}

};



class screen_two

{

public :

const std :: vector < screen_two_elements >& get_elements() const

{

return ...;

}

};



class cool_data_model

{

public :

typedef boost :: variant < screen_one, screen_two > screen;



template < typename NewScreenType >

void change_screen( const NewScreenType & new_val)

{

cur_screen_ = new_val;

}



template < typename VisitorType >

VisitorType :: result_type apply_visitor( const VisitorType & visitor)

{

return boost :: apply_visitor(visitor, cur_screen_);

}

private :

screen cur_screen_;

};









इस तरह के एक मॉडल को देखने (आकर्षित) करने के लिए, आपको आगंतुक तंत्र का उपयोग करने की आवश्यकता है। यह एक विशेष फ़नकार है जो एक प्रकार के प्रत्येक तत्व के लिए कोष्ठक संचालकों को परिभाषित करता है। हमारे मामले में, प्रत्येक राज्य के लिए।



class painter : public boost :: static_visitor <>

{

public :

void operator ()( const screen_one & val_screen)

{

// ,

val_screen.get_elements();

...

}

void operator ()( const screen_two & val_screen)

{

// ,

val_screen.get_elements();

...

}

};



model.apply_visitor(painter());









राज्य वर्ग उस समय के लिए आवश्यक डेटा संग्रहीत करता है जब स्क्रीन "चयनित स्थिति" में होती है और सभी विशिष्ट कार्यक्षमता प्रदान करती है। यदि आपको पहले वाले को वर्तमान के रूप में चुना जाता है, तो आपको दूसरी स्क्रीन की कार्यक्षमता के लिए नहीं मिलेगा।



सामान्य तौर पर, भौतिकी में "माप" के संचालन के लिए आगंतुकों की अवधारणा बहुत समान है। एक निश्चित प्रणाली है, हम इसे मापने वाला यंत्र लगाते हैं। हम परिणाम प्राप्त करते हैं, और / या सिस्टम की स्थिति को बदलते हैं।



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



All Articles