2014-09-02 6 views
6

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

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

एकमात्र समाधान जो मैं सोच सकता हूं वह है कि जानकारी को स्थिर रूप से उपलब्ध कराया जाए ताकि बेस क्लास उन्हें सहायता के बिना प्राप्त कर सके। लेकिन मैं इससे बचना चाहता हूं।

क्या बेस क्लास बनाने और प्रारंभ करने का कोई तरीका है और बाद में व्युत्पन्न प्रकार के उदाहरण को विस्तारित करना है? यदि नहीं, तो सी ++ की उपलब्ध सुविधाओं का उपयोग करके मैं सृजन और निर्भरताओं के इस आदेश को कैसे प्राप्त कर सकता हूं?

#include <string> 
#include <iostream> 
using namespace std; 

class Base { 
public: 
    Base(string name, int age) : name(name), age(age) {} 
protected: 
    const string name; 
    int age = 0; 
}; 

class Derived : public Base { 
    Derived() { // No parameters here, no call to base constructor 
     cout << "My name is " << name << " and I'm " << age << "." << endl; 
    } 
} 

Base base("Peter", 42); 
Derived derived(base); // "My name is Peter and I'm 42." 
+1

आपका "आधार निर्माता के लिए कोई कॉल नहीं" मुझे जवाब देता है: नहीं। ऐसा नहीं है कि सी ++ कैसे काम करता है। – Quentin

+1

टीएल; डीआर; [प्रोटोटाइप पैटर्न] (http://sourcemaking.com/design_patterns/prototype) आपके उपयोग के मामले में मदद कर सकता है। –

उत्तर

6

"जानकारी अभी नहीं होनी चाहिए" मेरे लिए लगता है यह दो संभव व्याख्याओं की अनुमति देता है जैसे:

  • जानकारी विश्व स्तर पर लगातार वास्तव में है और हार्ड-कोडेड हो सकता है:

    Derived() : Base("Peter", 42) {} 
    
  • आपका वास्तव में क्या मतलब था कि "आधार केवल वहां होना चाहिए":

    Derived(const Base & b) : Base(b) {} 
    
+0

जानकारी को हार्डकोड नहीं किया जा सकता है। हालांकि, दूसरा विकल्प दिलचस्प लग रहा है। क्या वह 'बेस' के डिफ़ॉल्ट प्रति कन्स्ट्रक्टर का उपयोग करेगा या क्या मुझे इसे स्वयं लागू करना होगा? – danijar

+0

यह डिफ़ॉल्ट प्रतिलिपि का उपयोग करेगा जब तक कि आप एक – Pete

+0

@danijar प्रदान नहीं करते: यह ओवरलोड रिज़ॉल्यूशन द्वारा 'बेस' के किसी भी प्रतिलिपि का चयन किया जाएगा ... –

3

एक विकल्प रचना का उपयोग किया जाएगा, जिसका अर्थ है कि BaseDerived का एक उदाहरण चर होगा:

#include <string> 
#include <iostream> 
using namespace std; 

class Base { 
public: 
    Base(string name, int age) : name(name), age(age) {} 
    const string name() { return name; } 
    int age() { return age; } 
protected: 
    const string name; 
    int age = 0; 
}; 

class Derived { 
    Derived(Base b): base(b) { // No parameters here 
     cout << "My name is " << base.name() << " and I'm " 
      << base.age() << "." << endl; 
    } 

private: 
    Base base;  
} 

Base base("Peter", 42); 
Derived derived(base); // "My name is Peter and I'm 42." 

सूचना कैसे Derived नहीं रह गया है Base फैली (शायद नाम परिवर्तित करने की आवश्यकता होगी) , और Base में एक आवृत्ति चर के लिए प्रत्येक कॉल अब एक विधि कॉल है।

5

किसी व्युत्पन्न प्रकार के लिए पहले से आवंटित प्रकार को विस्तारित करना किसी कारण से संभव नहीं है: यदि व्युत्पन्न प्रकार जोड़े गए फ़ील्ड, आप सही आकार को आगे कैसे निर्धारित करेंगे?

एक संभावित तरीका केवल एक निर्माता है जो Base उदाहरण स्वीकार कर रहा है, या शायद operator=

हालांकि आप इस उदाहरण में विरासत पर संरचना का उपयोग करने पर विचार करना चाह सकते हैं। यदि Base केवल Derived के लिए टेम्पलेट के रूप में कार्य करता है, तो यह विरासत संबंध का एक अच्छा उदाहरण नहीं है।

+0

मैं संरचना पर विचार करता हूं, लेकिन यह गलत लगता है।मेरे आवेदन में, यह उन घटकों के बारे में है जो नियमित रूप से अपडेट हो जाते हैं। संरचना का अर्थ यह होगा कि विशिष्ट घटक अब घटक नहीं हैं लेकिन "jetpacks" के साथ सामान्य कक्षाएं हैं। मेरा वर्तमान समाधान एक अतिरिक्त 'शून्य प्रारंभिक()' विधि प्रदान करना है जिसे सदस्यों को सेट करने के लिए निर्माण के बाद बाहरी रूप से बुलाया जाता है। हालांकि, मूल्य व्युत्पन्न कन्स्ट्रक्टर में तब उपलब्ध नहीं हैं। – danijar

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