2011-03-27 10 views
7

मैं उद्देश्य-सी और सी ++ मिश्रण कर रहा हूं। हालांकि मैं उद्देश्य-सी ++ के उपयोग को कम करना चाहता हूं। क्योंकि इसमें उद्देश्य-सी और सी ++ दोनों में कुछ प्रकार की सीमाएं हैं।उद्देश्य-सी ++ के उपयोग को कम करने के उद्देश्य से सी ++ वर्ग का उपयोग करने के लिए अनुशंसित तरीका?

वर्तमान में, मैं इसका उपयोग इस तरह कर रहा हूं।

// A.h, Objective-C 
#import "B.h" 
@interface A 
{ 
    B* b; 
} 
@end 

// B.h, Objective-C++ 
@interface B 
{ 
    void* c; 
} 

// C.h, C++ 
class C 
{ 
}; 

मैं B.h में C.h शामिल करना चाहते हैं, लेकिन अगर मैं यह किया, B.hA.h में आयात नहीं किया जा सकता। इसलिए मुझे cvoid* प्रकार के रूप में चर छोड़ना है। यह एक बड़ी समस्या नहीं है क्योंकि मैं के सदस्यों का उपयोग B.m फ़ाइल में स्वतंत्र रूप से कर सकता हूं। लेकिन मुझे हमेशा इसे डालना पड़ता है। यह कुछ अस्पष्ट लगता है। इसलिए यदि यह है तो मैं बेहतर तरीके से उपयोग करना चाहता हूं।

उत्तर

15

ऐसा करने के कुछ तरीके हैं, लेकिन मेरी राय में 'PIMPL' idiom का उपयोग करने का सबसे अच्छा तरीका है, जो सी ++ में काफी आम है। हेडर शुद्ध उद्देश्य-सी और शुद्ध सी ++ को पॉइंटर्स के साथ वास्तविक कार्यान्वयन वाली अग्रेषित घोषित संरचना में बनाएं। यह .mm फ़ाइल में परिभाषित किया गया है, और उसके बाद उद्देश्य-सी ++ का उपयोग कर सकते हैं।

अपने उदाहरण में, आप कुछ इस तरह करना होगा:

// B.h, pure Objective-C: 
struct BImpl; 
@interface B 
{ 
    struct BImpl* impl; 
} 
// ... 


// B.mm, mixed: 
#include "C.h" 
struct BImpl // since this is C++, it can actually have constructors/destructors 
{ 
    C* my_c; 
    BImpl() : my_c(new C) {} 
    ~BImpl() { delete my_c; my_c = NULL; } 
}; 
// make sure to alloc/initialise impl (using new) in B's init* methods, 
// and free it (using delete) in the dealloc method. 

मैं वास्तव में वास्तव में इस समस्या को हल पर एक लेख लिखा है, आप देख सकते यह उपयोगी: http://philjordan.eu/article/strategies-for-using-c++-in-objective-c-projects - यह भी के कुछ अन्य तरीकों से पता चलता ऐसा कर रहा है, जिसमें आपके मूल void* दृष्टिकोण शामिल हैं।

+4

मैं इसे उत्तर के रूप में चुनने के लिए शेष 4 मिनट तक प्रतीक्षा नहीं कर सकता! – Eonil

4

जैसा कि pmjordan ने his blog article में लिखा था, @interface घोषणा के भीतर BImpl को निम्नानुसार 'संरचना' कीवर्ड की आवश्यकता है।

struct BImpl; 
@interface B 
{ 
    struct BImpl* impl; 
} 

मुझे लगता है कि उसने अनजाने में इसे छोड़ दिया है। यदि आपके पास बहुत अधिक * .m फ़ाइलें हैं, तो आपको इस हेडर को शामिल करने की आवश्यकता है, इससे बहुत बड़ा अंतर होता है। जोड़ा गया 'स्ट्रक्चर' कीवर्ड उद्देश्य-सी संकलक को इस हेडर को अन्य .m फ़ाइलों के लिए शुद्ध सी के रूप में समझने के लिए कारण बनाता है जो इस हेडर को आयात करता है। अन्यथा अन्य * .m फ़ाइलें जो इस शीर्षलेख को आयात करती हैं उन्हें संकलित नहीं किया जाएगा। यह छोटा समाधान आपको * .m फ़ाइलों को .mm फ़ाइलों में बदलने से बचाता है। कभी-कभी, मूल .m फ़ाइलों को .mm में बदलना बहुत संकलन त्रुटियों का कारण बनता है।

+0

क्या आप pmjordan के ब्लॉग आलेख को एक लिंक जोड़ सकते हैं? – Stephan

+0

हाँ, मैंने किया। वास्तव में, pmjordan इस सवाल के पहले जवाब के लेखक हैं। मुझे मूल उत्तर से लिंक मिला। आप अपने उत्तर में मूल लिंक का भी उपयोग कर सकते हैं। – DuncanSungWKim

+1

यह उत्तर पहले उत्तर में शामिल किया गया है। इस जवाब को पोस्ट करने के बाद मैं अपने सुझाव को अपनाने के लिए वास्तव में @pmjordan का धन्यवाद करता हूं। – DuncanSungWKim

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