2011-03-27 19 views
7

Objective-C ve C++'ları karıştırıyorum. Ancak Objective-C++ kullanımını en aza indirmek istiyorum. Çünkü hem Objective-C hem de C++ 'da bir çeşit limitler vardır.C++ sınıfını Objective-C sınıfını Objective-C++ kullanımını en aza indirgemek için önerilen yol

Şu an bunu kullanıyorum.

// 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 
{ 
}; 

ben B.h içinde C.h dahil etmek istiyorum ama yaparsam B.hA.h içine alınamaz. Bu yüzden c değişkenini void* türünde bırakmak zorundayım. Bu büyük bir sorun değil çünkü C üyelerini B.m dosyasında serbestçe kullanabilirim. Ama her zaman onu yapmak zorundayım. Bu belli olmayan bir şey hissediyor. Bu yüzden daha iyi bir yol kullanmak istiyorum.

cevap

15

Bunu yapmanın birkaç yolu vardır, ancak bence en iyi yöntem, C++ 'da oldukça yaygın olan 'PIMPL' idiom kullanmaktır. Gerçek uygulamayı içeren ileri bildirimli bir yapıya işaretçilerle başlıkları saf Objective-C ve saf C++ yapın. Bu, .mm dosyasında tanımlanır ve Objective-C++ 'yi kullanabilir. o da bazı başka yollar gösterir - http://philjordan.eu/article/strategies-for-using-c++-in-objective-c-projects: En örnekte

, böyle bir şey yapacağını: Aslında tam olarak bu sorunun çözümü hakkında bir makale yazdım

// 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. 

, bunu yarayabilecek Orijinal void* yaklaşımınız dahil olmak üzere, bunu yapıyor.

+4

Yanıt olarak bunu seçmek için 4 dakika bekleyemiyorum! – Eonil

4

pmjordan'ın his blog article'da yazdığı gibi, @interface declaration içindeki BImpl 'struct' anahtar sözcüğünü aşağıdaki gibi gerektirir.

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

Sanırım yanlışlıkla onu dışarıda bıraktı. Çok sayıda * .m dosyanız olduğunda bu başlığı eklemeniz gerekiyorsa, bu büyük bir fark yaratır. Eklenen 'struct' anahtar sözcüğü, Objective-C derleyicisinin, bu üstbilgiyi içe aktaran diğer .m dosyaları için bu üstbilgiyi salt C olarak algılamasına neden olur. Aksi takdirde, bu üstbilgiyi içe aktaran diğer * .m dosyaları derlenmeyecektir. Bu küçük çözüm, * .m dosyalarını .mm dosyalarına değiştirmenizi sağlar. Bazen, orijinal .m dosyalarını .mm olarak değiştirmek çok sayıda derleme hatasına neden olur.

+0

pmjordan'ın blog yazısına bir link ekleyebilir misiniz? – Stephan

+0

Evet, yaptım. Aslında, pmjordan bu sorunun ilk cevabının yazarıdır. Bağlantıyı orijinal cevaptan aldım. Orijinal bağlantıyı kendi yanıtında da kullanabilirsiniz. – DuncanSungWKim

+1

Bu cevap ilk cevaba dahil edilmiştir. Bu cevabı gönderdikten sonra önerimi kabul ettiğim için çok teşekkür ederim. – DuncanSungWKim

İlgili konular