2011-10-14 11 views
9

चलो कहते हैं कि मैं दो अलग-अलग वर्गों करते हैं, दोनों का प्रतिनिधित्व 2 डी निम्नलिखित की तरह एक ही आंतरिक रास्ते में डेटा समन्वय: दो वर्गों समान और ऊपर समारोह किया जा रहा है यह देखते हुएदो समान वर्गों के पॉइंटर्स के बीच कास्टिंग की सुरक्षा?

class LibA_Vertex{ 
    public: 
    // ... constructors and various methods, operator overloads 
    float x, y 
}; 

class LibB_Vertex{ 
    public: 
    // ... same usage and internal data as LibA, but with different methods 
    float x, y 
}; 


void foobar(){ 
    LibA_Vertex * verticesA = new LibA_Vertex[1000]; 
    verticesA[50].y = 9; 
    LibB_Vertex * verticesB = reinterpret_cast<LibB_Vertex*>(vertexA); 
    print(verticesB[50].y); // should output a "9" 
}; 

, मैं मज़बूती से इस सूचक रूपांतरण पर भरोसा कर सकते हर मामले में उम्मीद के रूप में काम कर रहे हैं?

(पृष्ठभूमि, यह है कि मुझे वर्टेक्स कक्षाओं के समान दो अलग-अलग पुस्तकालयों के बीच वर्टेक्स सरणी का व्यापार करने का एक आसान तरीका चाहिए, और मैं अनावश्यक रूप से सरणी की प्रतिलिपि से बचना चाहता हूं)।

उत्तर

13

सी ++ 11 ने लेआउट-संगत नामक अवधारणा को जोड़ा जो यहां लागू होता है।

दो मानक लेआउट struct(धारा 9) प्रकार कर रहे हैं लेआउट संगत अगर वे गैर स्थिर डेटा सदस्यों और इसी गैर स्थिर डेटा सदस्यों (घोषणा क्रम में) की समान संख्या है लेआउट-संगत प्रकार (3.9)।

जहां

एक मानक लेआउट वर्ग है एक वर्ग है कि:

  • प्रकार गैर मानक लेआउट वर्ग का कोई गैर स्थिर डेटा सदस्यों (या ऐसे प्रकार के सरणी) या संदर्भ,
  • में कोई वर्चुअल फ़ंक्शन (10.3) नहीं है और वर्चुअल बेस क्लासेस (10.1),
  • में सभी गैर-स्थिर डेटा मीटर के लिए समान पहुंच नियंत्रण (क्लॉज 11) है एम्बर,
  • में कोई गैर-मानक-लेआउट बेस क्लास नहीं है,
  • या तो अधिकांश व्युत्पन्न वर्ग में गैर-स्थैतिक डेटा सदस्य नहीं हैं और गैर-स्थिर डेटा सदस्यों वाले अधिकांश बेस क्लास में हैं, या उनके पास कोई बेस क्लास नहीं है गैर स्थैतिक डेटा सदस्य, और
  • में पहले गैर-स्थैतिक डेटा सदस्य के समान प्रकार के आधार वर्ग नहीं हैं।

एक मानक लेआउट struct एक मानक लेआउट वर्गवर्ग-कुंजीstruct या वर्ग-कुंजीclass साथ परिभाषित किया गया है।

एक मानक लेआउट संघ एक मानक लेआउट वर्गवर्ग-कुंजीunion साथ परिभाषित किया गया है।

को सीवी-योग्य और लेआउट संगत प्रकार के सीवी-अयोग्य संस्करणों (3.9.3) एक ही मूल्य प्रतिनिधित्व और संरेखण आवश्यकताओं होगा (3.11) अंत में

संकेत करती हैं।

जो गारंटी देता है कि reinterpret_cast किसी भी लेआउट को किसी भी लेआउट-संगत प्रकार में पॉइंटर में बदल सकता है।

+3

इन रूपांतरणों को करने का एक और अच्छी तरह से परिभाषित तरीका एक सामान्य प्रारंभिक अनुक्रम के साथ एक संघ का उपयोग करना है (जैसा कि '§9.2/1 9' द्वारा अनुमत है)। – Mankarse

+0

ओह! खैर, सी ++ 11 बचाव के लिए। मुझे उम्मीद है कि यह चीजों में से एक था VS2010 ने मानक के माध्यम से चेरी चुनने के दौरान जोड़ने का फैसला किया। –

+1

@Clairvoire: यह उन चीजों में से एक है जो हमेशा अभ्यास में काम करते थे, भले ही औपचारिक रूप से मना किया गया हो। मुझे उम्मीद नहीं है कि किसी भी कंपाइलर लेखकों को समर्थन "जोड़ना" था। उद्धरण के लिए –

1

मैं उस वर्ग को एक वर्ग में लपेटूंगा (ताकि यदि आपको प्लेटफ़ॉर्म या कुछ बदलना होगा, तो कम से कम एक स्थान पर स्थानांतरित होना चाहिए) लेकिन हाँ यह संभव होना चाहिए।

आप reinterpret_cast का उपयोग करना चाहेंगे, static_cast भी नहीं।

+0

ठीक है आप मेरी गलती हैं! प्रश्न –

1

सैद्धांतिक रूप से यह एक अनिर्धारित व्यवहार है। हालांकि, यह कुछ सिस्टम/प्लेटफार्मों में काम कर सकता है।

मेरा सुझाव है कि आप में 1. अर्थात

class Lib_Vertex{ 
// data (which is exactly same for both classes) 
public: 
// methods for LibA_Vertex 
// methods for LibB_Vertex 
}; 

एक class में जोड़ा जा रहा है तरीकों 2 वर्गों विलय करने के लिए अपने आकार को प्रभावित नहीं करेगा प्रयास करना चाहिए होगा। आपको अपना डिज़ाइन थोड़ा बदलना पड़ सकता है लेकिन यह इसके लायक है।

+0

आमतौर पर, मैं इस तरह कुछ भी उपयोग करता हूं। मुझे अभी भी सरणी की प्रतियां बनाना होगा। एक लाइब्रेरी (2 डी भौतिकी मुक्ति) इसके आंतरिक वर्टेक्स वर्ग का उपयोग करके शिखर के पूरे सरणी लौटाती है, जिसे मुझे दूसरी लाइब्रेरी (2 डी प्रतिपादन lib) में फ़ीड करने की आवश्यकता होती है जो इसके आंतरिक वर्टेक्स वर्ग के सरणी स्वीकार करता है। –

0

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

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