कास्ट क्लास ऑब्जेक्ट टू स्ट्रक्चर ऑब्जेक्ट C / C ++

Nov 27 2020

मेरे पास C में दो प्रोजेक्ट्स हैं और C ++ में दूसरा और मैं C ++ में एक स्ट्रक्चर ऑब्जेक्ट में C ऑब्जेक्ट में क्लास ऑब्जेक्ट डालने की कोशिश करता हूं। उदाहरण के लिए, मेरे पास myClass की एक ऑब्जेक्ट है जिसे मैं myStru में डालने की कोशिश कर रहा हूं:

मेरे C ++ प्रोजेक्ट में मेरे पास यह वर्ग है:

class myClass{
    myClass();
    ~myClass();
    char    *data;
    int     var;
}

मेरी सी परियोजना में मेरे पास यह संरचना है:

struct myStru {
    char  *data;
    int    var;
};
typedef struct myStru myStru;

अब मेरी C ++ प्रोजेक्ट में से मैं एक ऑब्जेक्ट बनाता हूं myClass:

myClass *classObj = new myClass();
classObj->data = new char[10];
classObj->var  = 99;

मेरी सी परियोजना में मुझे classObjएक शून्य सूचक के रूप में प्राप्त होता है और मैं इसे इस प्रकार डालने की कोशिश करता हूं:

myStru *struObj = (myStru*)malloc(sizeof(struct myStru));
struObj = (myStru*) classObj;
printf(" struObj->var %d \n", struObj->var); // this print 99

मैं इसे बाद में अपने C ++ प्रोजेक्ट में करता हूं

   delete []classObj->data; // I know smart pointers can be used here but this is not my point in this question now
    delete  classObj;

मैं यहाँ क्या कर रहा हूँ? यानी, कास्टिंग classObjके लिए struObjहै कि रास्ते में?

पूरा उदाहरण यहां पाया जा सकता है (धन्यवाद @Borgleader) http://coliru.stacked-crooked.com/a/05543b944ee23f2f

संपादित करें: मुझे इस लेख में मेरे प्रश्न का अच्छा उत्तर मिला (देखें C से C ++ वर्ग तक पहुँच प्राप्त करें): https://www.oracle.com/technical-resources/articles/it-infrastructure/mixing-c-and-cplusplus.html

जवाब

3 BartekBanachewicz Nov 27 2020 at 13:22

मैं 100% निश्चित नहीं हूं, क्योंकि यह C ++ है और आप कभी नहीं हो सकते, लेकिन मुझे लगता है कि यह अपरिभाषित व्यवहार है।

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

यह काम कर सकता है यदि आपको वास्तव में इसके बजाय अपनी कक्षा विरासत में मिली है।

वैकल्पिक रूप से, अन्य अपवाद यह है कि आप memcpyऐसी संरचनाओं के बीच सुरक्षित रूप से AFAIR कर सकते हैं ।

1 Persixty Nov 27 2020 at 17:08

यह प्रश्न अंतर-संचालन के बारे में है और आपको इसका निश्चित उत्तर कभी नहीं मिलेगा क्योंकि यह C और C ++ कंपाइलर के क्रियान्वयन परिभाषित पहलुओं पर निर्भर करता है। structऔर classसी ++ मामले में लेआउट संगत प्रकार हैं। यह बहुत स्पष्ट है कि एक की घोषणा करना classऔर एक structमुद्दा नहीं है और क्योंकि वे दोनों अपने सभी सदस्यों के लिए एक ही सदस्य-पहुंच रखते हैं (हालांकि एक दूसरे से अलग) संगत हैं (कम से कम C ++ 14 बाद में मेरा मानना ​​है) ।

सबसे अच्छा मानक पेश करने जा रहा है:

नोट: मानक-लेआउट कक्षाएं अन्य प्रोग्रामिंग भाषाओं में लिखे गए कोड के साथ संचार करने के लिए उपयोगी हैं। उनका लेआउट 12.2 में निर्दिष्ट है। - अंतिम नोट

इरादा है कि इस तरह की कक्षाओं (जो दोनों मानक लेआउट और लेआउट संगत कर रहे हैं) अंतर-प्रचलित हो रहा है। यदि आप एक ही कंपाइलर का उपयोग दो मोड में कर रहे हैं तो यह 'निराशाजनक' होगा यदि यह काम नहीं करता है। लेकिन यह सबसे अच्छा है कि आपको 'निराशाजनक' मिलेगा - दस्तावेज की जांच करें।

मैं समग्र रणनीति के बारे में संसाधन प्रबंधन के बारे में थोड़ा आश्चर्य करता हूं। आपने C ++ में एक विध्वंसक घोषित किया है classऔर यह ठीक नहीं है virtual!), लेकिन आप इसे structC साइड पर कॉपी करते हैं , यदि C कोड में इसकी वस्तुओं को नष्ट करने के लिए 'विध्वंसक' कार्य होता है, जिससे आपको परेशानी हो सकती है। 'बिट बिटवाइज़ C ++ ऑब्जेक्ट (उम्मीद है!) को क्लोन किया।

यदि C ने free(s->data)C ++ में निर्मित किसी वस्तु की अपनी कॉपी पर कॉल किया है, जिसका उपयोग newआपने अनफाइंड बिहेवियर को भड़काने के लिए किया है । यह अपवाद हो सकता है कि malloc()संगतता के लिए C ++ पक्ष पर वारंट का उपयोग किया जाए।

तो यह शायद ठीक है, लेकिन आप सी और सी ++ के बीच अंतर-संचालन क्षमताओं पर भरोसा कर रहे हैं और दो मानक आपको जहां तक ​​यह ले जा सकते हैं, लेकिन परिभाषा के अनुसार आप कार्यान्वयन परिभाषित सुविधाओं का उपयोग कर रहे हैं।

उस नोट से हम जानते हैं कि मानक काम करने के लिए तैयार है और यह शायद करेगा। सौभाग्य!