2010-05-06 25 views
5

मैं C++प्रवेश व्युत्पन्न एक आधार वर्ग सूचक

एक सरल कंसोल खेल बनाने रहा हूँ के साथ वर्ग के सदस्यों मैं अगर मैं एक सूचक है कि की ओर इशारा करते है का उपयोग करते हुए 'entPlayer' वर्ग के सदस्यों का उपयोग कर सकते जानना चाहते हैं आधार वर्ग ('इकाई'):

class Entity { 
public: 
    void setId(int id) { Id = id; } 
    int getId() { return Id; } 
protected: 
    int Id; 
}; 

class entPlayer : public Entity { 
    string Name; 
public: 
    void setName(string name) { Name = name; } 
    string getName() { return Name; } 
}; 

Entity *createEntity(string Type) { 
    Entity *Ent = NULL; 
    if (Type == "player") { 
     Ent = new entPlayer; 
    } 
    return Ent; 
} 

void main() { 
    Entity *ply = createEntity("player"); 
    ply->setName("Test"); 
    ply->setId(1); 

    cout << ply->getName() << endl; 
    cout << ply->getId() << endl; 

    delete ply; 
} 

मैं कैसे ply-> setName आदि फोन करने में सक्षम हो सकता है?

या

तो यह संभव है कि जिस तरह से नहीं है, क्या एक बेहतर तरीका हो सकता है?

+1

क्षमा करें, मुझे आपके कोड स्वरूपण को संपादित करना था। खाली लाइनों ने आपका कोड वास्तव में लंबा बना दिया! आपके कोड के बारे में एक और छोटी टिप्पणी: एक सतत नामकरण सम्मेलन के साथ छड़ी उदा। AllClassNamesLikeThis, और पैरामीटर_नाम_like_थिस। एक और नाइट: आप बाद में बट में अपने आप को "ent" जैसे संक्षेप में लात मार देंगे। मैं ईमानदारी से यह नहीं बता सकता कि एंटरप्लेयर क्या होना चाहिए। मुझे लगता है कि आपका मतलब सिर्फ "प्लेयर" है, या यदि आप वर्बोज़ "प्लेयरइन्टिटी" महसूस कर रहे हैं। – allyourcode

उत्तर

11

एक कास्ट का उपयोग करके यह संभव है। आप एक तथ्य व्युत्पन्न वर्ग की एक वस्तु के आधार वर्ग सूचक अंक, आप उपयोग कर सकते हैं कि static_cast के लिए जानते हैं:

Entity* e = /* a pointer to an entPlayer object */; 
entPlayer* p = static_cast<entPlayer*>(e); 
p->setName("Test"); 

आप निश्चित रूप से पता नहीं है, तो आप dynamic_cast का उपयोग करें और परीक्षण की आवश्यकता परिणाम यह देखने के लिए कि यह शून्य नहीं है। ध्यान दें कि यदि बेस क्लास में कम से कम एक वर्चुअल फ़ंक्शन है तो आप केवल dynamic_cast का उपयोग कर सकते हैं। एक उदाहरण:

Entity* e = /* a pointer to some entity */; 
entPlayer* p = dynamic_cast<entPlayer*>(e); 
if (p) 
{ 
    p->setName("Test"); 
} 

कहा यही कारण है, यह कहीं बेहतर होगा बहुरूपता का उपयोग कर (अर्थात आभासी कार्यों) अपने वर्ग की कार्यक्षमता को संपुटित करने के लिए।

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

entPlayer * pPlayer = dynamic_cast<entPlayer *>(pointer_to_base); 

यह (यदि सफल) एक व्युत्पन्न सूचक का परिणाम देगा:

+0

मेरे पास एक संबंधित प्रश्न था, जो यह उत्तर उत्तर देता है: डी जो मैं जानना चाहता था वह था "मैं कैसे बता सकता हूं कि मेरा आधार सूचक वास्तव में व्युत्पन्न वस्तु को इंगित करता है या नहीं?"।जो जवाब मैं जोड़ रहा हूं वह गतिशील_कास्ट का उपयोग करता है (केवल तभी काम करता है जब बेस क्लास में वर्चुअल फ़ंक्शन हो)। फिर, देखें कि परिणाम न्यूल है या नहीं। #victorybaby – allyourcode

+0

यह भी (आंशिक रूप से) एक और प्रश्न का उत्तर देता है जो मैंने सी ++ के बारे में थोड़ी देर के लिए किया है: विभिन्न प्रकार के कास्टों के बीच क्या अंतर है? यकीन है कि उनमें से एक अच्छी संख्या है! – allyourcode

0

आप एक गतिशील डाली कर सकते हैं।

अन्यथा NULL वापस कर दिया गया है।

1

मैं कुछ इस तरह कर रही है पर विचार करेंगे: क्योंकि यह शायद नहीं है कि आप क्या कर किया जाना चाहिए,

public: 
void setId(int id) 
{ 

    Id = id; 

} 

void virtual setName(string name) = 0; // Virtual Function 
string virtual getName() = 0; // Virtual Function 

int getId() { return Id; } 

protected: 
    int Id; 

}; 

class entPlayer : public Entity { 

    string Name; 

public: 
    entPlayer() { 

     Name = ""; 
     Id = 0; 

    } 

    void entPlayer::setName(string name) { // Must define function 

     Name = name; 
} 

string entPlayer::getName() { return Name; } // again must define function here 

}; 
0

सी ++ तुम सच में अजीब करने के लिए कोशिश कर रहे हैं बनाता है, और यह अच्छा करने के लिए आप का नेतृत्व करने के प्रयास कर रहा है वस्तु उन्मुख डिजाइन। वास्तव में, डिफ़ॉल्ट रूप से, compilers often disable run-time type information (आरटीटीआई), जिसे गतिशील_कास्ट काम करने के लिए आवश्यक है।

अपने व्यापक संदर्भ को जानने के बिना, यह कहना मुश्किल है कि आपको इसके बजाय क्या करना चाहिए। मैं क्या कह सकता हूं कि यदि आप एक और विशिष्ट सूचक चाहते थे, आपको पर एक अंगूठी डालना चाहिए था, तो आपको लगभग Entity* लौटने वाले फ़ंक्शन का उपयोग नहीं करना चाहिए, और शायद एक बेहतर दृष्टिकोण है।

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