2013-03-05 10 views
5

मुझे शैली के बारे में एक सवाल है। मेरे पास एक वर्ग है (मेरे मामले में एक विकल्प) जो एक एक्सोजेनिक ऑब्जेक्ट (ब्याज दर) के मूल्य पर निर्भर करता है। मेरा लक्ष्य exogenous ऑब्जेक्ट (दर) के लिए एक सार आधार वर्ग बनाना है ताकि मैं विविधताएं बना सकूं, सिम्युलेरेट या कॉन्स्टेंट्रेट कहें, जो मेरे निर्भर वर्ग, विकल्प के अंदर काम करेगा।सी ++: एक सदस्य के रूप में एक अमूर्त वर्ग

हालांकि, मुझे सी ++ में मिल रहा है, क्योंकि मैं स्पष्ट रूप से एक सार आधार वर्ग को चालू नहीं कर सकता, मुझे या तो एक सूचक या बेस क्लास के संदर्भ को स्टोर करना होगा। मेरी चिंता यह है कि जब तत्काल एक्सोजेनस ऑब्जेक्ट्स निर्भर वर्ग के बाहर गुंजाइश से बाहर निकलते हैं, तो मेरा आश्रित वर्ग जंक पर इंगित करेगा।

क्या सी ++ में इस समस्या के लिए बहुरूपता का उपयोग करने का कोई उचित तरीका है?

मेरे वर्तमान कोड:

class Dependent 
{ 
public: 
    Dependent(const Exogenous& exo) : exo_(exo) {} 
    double getSomething() const { exo_.interfaceMethod(); } 
private: 
    Exogenous& exo_; 
} 

class Exogenous 
{ 
public: 
    virtual double interfaceMethod() const=0; 
} 

class ExogenousVariationA 
{ 
public: 
    virtual double interfaceMethod() const { return resultA; } 
} 

class ExogenousVariationB 
{ 
public: 
    virtual double interfaceMethod() const { return resultB; } 
} 
+0

क्या 'आश्रित' अनिवार्य रूप से 'एक्सोजेनस' का संदर्भ रखेगा, या इससे प्राप्त हो सकता है? अर्थात। क्या आपको दोनों वर्गों को अलग से चालू करना है? – didierc

+0

सबसे पहले, पॉलीमोर्फिक ऑब्जेक्ट हमेशा पॉइंटर/संदर्भ द्वारा आयोजित किए जाते हैं। जावा जैसी अन्य भाषाओं में भी यह मामला है। दूसरा, चूंकि यह सी ++ है, आपको हमेशा उचित सी ++/आरएआईआई ऑब्जेक्ट आजीवन प्रबंधन का उपयोग करना चाहिए, जो पॉइंटर्स के लिए स्मार्ट पॉइंटर्स का मतलब है। – bames53

उत्तर

3

sftrabbit को जो मैं जोड़ना होगा कुछ अच्छी सलाह है:

  • आप सार आधार वर्ग में एक virtualclone() विधि बना सकते हैं (यह एक आभासी आधार वर्ग नहीं है - कि कोई अन्य विषय) ; उस विधि को व्युत्पन्न ब्याज दर वर्गों में लागू किया जाएगा, एक नई स्वतंत्र ब्याज दर वस्तु के लिए एक सूचक वापस लौटाया जा सकता है जिसे विकल्प के स्वामित्व में रखा जा सकता है; यह विशेष रूप से उपयोगी होता है यदि ऑब्जेक्ट्स में डेटा होता है जो आप इसका उपयोग करते समय बदलते हैं (उदाहरण के लिए गणना या कैशिंग से)
  • शायद आपको यह नहीं चाहिए, लेकिन std/boost साझा पॉइंटर्स के साथ एक कमजोर पॉइंटर के लिए पूछना भी संभव है साझा वस्तु ...इस तरह आप चाहे वस्तु के "मालिकों" परीक्षण कर सकते हैं (जो आप शामिल नहीं किया जाएगा) पहले से ही इसके साथ समाप्त कर दिया है और इसके विनाश

अलग से शुरू हो रहा है तो रनटाइम बहुरूपता अपने ExogenousVariationA और ~ B वर्गों वास्तव में उपयोग करने के लिए करना चाहिए Exogenous से प्राप्त करें, और जिस विधि को आप पॉलिमॉर्फिक रूप से प्रेषित करना चाहते हैं वह virtual होना चाहिए। ऐसा लगता है:

class Exogenous 
{ 
public: 
    virtual double interfaceMethod() const=0; 
} 

class ExogenousVariationA : public Exogenous 
{ 
public: 
    double interfaceMethod() const { return resultA; } 
} 
+0

बिल्कुल सही! क्लोन() विधि बिल्कुल वही करेगी जो मुझे चाहिए। मैला उदाहरण कोड के लिए खेद है। – curltron

4

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

समाधान क्लाइंट को ऑब्जेक्ट के जीवनकाल में आपको किसी प्रकार की ज़िम्मेदारी देने के लिए मजबूर करना है। ऐसा करने का तरीका एक स्मार्ट सूचक के लिए पूछना है। आपकी समस्या के आधार पर, आप std::unique_ptr या std::shared_ptr चाहते हैं। यदि आप क्लाइंट या बाद वाले से स्वामित्व लेना चाहते हैं तो पूर्व का उपयोग करें यदि आप उनके साथ स्वामित्व साझा करना चाहते हैं। मान लीजिए कि आप std::unique_ptr चुनें मान लीजिए, के रूप में आप तो अपने Dependent वर्ग निर्धारित करना होगा:

class Dependent 
{ 
public: 
    Dependent(std::unique_ptr<Exogenous> exo) : exo_(std::move(exo)) {} 
    double getSomething() const { exo_->interfaceMethod(); } 
private: 
    std::unique_ptr<Exogenous> exo_; 
} 

ग्राहक यह इतना तरह का प्रयोग करेंगे:

std::unique_ptr<Exogenous> ptr(new ExogenousVariationA()); 
Dependent dep(std::move(ptr)); 

अब, जब आपके ग्राहक आप के लिए std::unique_ptr गुजरता है, वे ' आप वस्तु के स्वामित्व दे रहे हैं। ऑब्जेक्ट केवल तभी नष्ट हो जाएगा जब आपकेstd::unique_ptr नष्ट हो गया है (जो तब होगा जब आपका Dependent नष्ट हो गया है, क्योंकि यह सदस्य है)।

वैकल्पिक रूप से, यदि आप std::shared_ptr लेते हैं तो क्लाइंट और आपके std::shared_ptr एस दोनों नष्ट होने के बाद ऑब्जेक्ट नष्ट हो जाएगा।

+0

मैं उम्मीद कर रहा था कि मैं स्मार्ट पॉइंटर्स से बच सकता हूं, लेकिन यह अभी भी एक उत्कृष्ट समाधान है। धन्यवाद। – curltron

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