2012-08-25 12 views
6

static_cast के लिए ठीक है उदाहरण के लिए, map<int,void*>hold का प्रस्ताव दें जहां void* हमेशा classA से पॉइंटर्स संग्रहीत कर रहा है क्या यह बाद में static_cast के माध्यम से इसे कास्ट करना सुरक्षित है? क्योंकि hold एक वर्ग कुछ cpp फ़ाइलें द्वारा इस्तेमाल किया एक हैडर जो क्या classA है पता नहीं है पर परिभाषित के सदस्य हैक्या यह एक शून्य * पॉइंटर

classA* ptr = static_cast<classA*>(holditerator->second); 

कारण void* प्रयोग किया जाता है। मुझे इन सीपीपी फाइलों पर classA परिभाषाओं का शीर्षलेख शामिल करना होगा जो कई कारणों से नहीं किया जा सकता है।

+1

आप ऐसा क्यों करेंगे? कृपया अधिक संदर्भ प्रदान करें क्योंकि अधिक उपयुक्त समाधान होने की संभावना है। – Johnsyweb

+0

आप पहले स्थान पर मानचित्र का उपयोग क्यों नहीं करते? – BatchyX

+0

@ बैचएक्स मैं अनुमान लगा रहा हूं कि 'होल्ड' में केवल कक्षा ए * नहीं है? –

उत्तर

13

हां, static_cast उस मामले में ठीक है और उपयोग करने के लिए सही चीज़ है।

मुझे यह पूछना है कि क्यों आप पहले स्थान पर classA* पॉइंटर्स स्टोर नहीं करते हैं। आप इसे में व्युत्पन्न वर्ग संकेत डाल करने के लिए चाहते हैं, तो सावधान रहना , आप आप उन्हें मानचित्र में डाल दिया से पहले classA*को/upconvert (परोक्ष या स्पष्ट) Upcast को व्युत्पन्न वर्ग संकेत की जरूरत है।

लेकिन यदि आप नक्शा में क्लास पॉइंटर्स भी व्युत्पन्न करते हैं, तो बेस क्लास पॉइंटर पर्याप्त होगा क्योंकि व्युत्पन्न क्लास पॉइंटर बेस क्लास पॉइंटर पर पूरी तरह से परिवर्तनीय है।

कारण शून्य * का उपयोग किया जाता है क्योंकि होल्ड कुछ सीपीपी फाइलों द्वारा उपयोग किए जाने वाले शीर्षलेख पर परिभाषित कक्षा का सदस्य होता है जो नहीं जानता कि क्लास क्या है।

यह लेयरिंग उल्लंघनों को रोकने के लिए एक वैध कारण हो सकता है।

मुझे इन सीपीपी फ़ाइलों पर कक्षा ए परिभाषाओं का शीर्षलेख शामिल करना होगा जो कई कारणों से नहीं किया जा सकता है।

यह आपके मामले में सबसे अधिक आवश्यक नहीं है। एक आगे की घोषणा पर्याप्त है। यदि हेडर जानता है कि मानचित्र में क्या रखा गया है, लेकिन केवल अतिरिक्त हेडर सहित टालना चाहता है, तो यह रास्ता है।

+0

उद्देश्य फिट बैठता है मैंने प्रश्न –

2

शीर्षक में शून्य * लेखन सिर्फ इसलिए कि नक्शे के उन वास्तविक प्रकार के बारे में पता नहीं करना चाहिए नहीं एक अच्छा विचार है, तो आप अपने कोड में हर जगह प्रकार सुरक्षा खोना जैसे स्थानों जो ClassA के बारे में पता कर में शामिल है, ।

पर विचार करें

  1. एक वर्ग जो अपने कोड के हर हिस्से के बारे में पता कर सकते हैं से ClassA पाने,
  2. एक वस्तु जो कोड के उन हिस्सों है से निपटने के लिए करने के लिए एक इंटरफेस प्रदान में नक्शा लपेटकर नक्शा है, लेकिन ClassA के साथ नहीं,
  3. की घोषणा है, लेकिन अपने हेडर फाइल में कक्षा ClassA को परिभाषित नहीं (खतरनाक वस्तुओं कुछ जगह है जहाँ ClassA घोषित किया जाता है पर नष्ट कर रहे हैं, लेकिन परिभाषित नहीं करता है, तो हो सकता है),
  4. टेम्पलेट का उपयोग कर,
  5. कक्षा को लागू करने वाले मानचित्र को व्युत्पन्न उपclass के रूप में लागू किया गया है, जैसे नक्शा फ़ील्ड व्युत्पन्न उपclass में रखा जा सकता है।

प्वाइंट 5: चित्रण (= टेम्पलेट पैटर्न)

class Containing { 
    private: 
     map<int,void*> myMap; 
    public: 
     void somePublicFunction() { // ...implementation } 
}; 

के बजाय आप

// Containing.h 
class Containing { 
    protected: 
     virtual void doSomething() = 0; 
    public: 
     static Containing* Create(); 
     void somePublicFunction() { doSomething(); } 
     virtual ~Containing() { } 
}; 

// Containing.cc 
#include ContainingImplementation.h 
Containing* Containing::Create() { return new ContainingImplementation; } 

// ContainingImplementation.h/cc 
class ContainingImplementation : public Containing { 
    protected: 
     virtual void doSomething() { // ... } 
    private: 
     map<int,ClassA*> myMap; 
    public: 
     virtual ~ContainingImplementation() { } 
}; 
6

के रूप में जोहानिस समझाया लिखते हैं, static_cast ठीक है। सीपीपी फाइलों में ClassA पर निर्भरताओं को रोकने के लिए एक और तकनीक pimpl idiom का उपयोग करना है।

// in header file 
class classB { 
public: 
    classB(); 
    ~classB(); 
private: 
    class impl; 
    unique_ptr<impl> pimpl; 
}; 



// in implementation file 
#include "classA.hpp" 

class classB::impl 
{ 
    std::map<int, classA> hold; // hidden in implementation file 
}; 

classB::classB() : pimpl{ new impl{ /*...*/ } } { } 
classB::~classB() { } 
+1

उत्कृष्ट विचार संपादित किया है :) –