2009-06-29 4 views
5

Objective-C 및 C++을 혼합해야합니다. 한 클래스 안에 모든 C++ 물건을 숨기고 모든 다른 것들을 Objective-C로 유지하고 싶습니다. 문제는 인스턴스 변수로 C++ 클래스가 필요하다는 것입니다. 이것은 헤더 파일에 언급되어야한다는 것을 의미합니다. 헤더 파일은 다른 클래스에 포함되어 C++이 전체 응용 프로그램에 확산되기 시작합니다. 지금까지 나와 함께 할 수 있었던 최상의 해결책은 다음과 같습니다.Objective-C 클래스의 인스턴스 변수로 C++ 클래스

이 방법이 효과적입니다. 구현 파일은 mm 확장자를 가지므로 Objective-C와 C++가 섞여 컴파일되고 #ifdef은 C++을 잠금 해제합니다. 다른 Objective-C 클래스가 헤더를 가져 오면 C++ 항목은 숨겨지고 클래스는 특별한 것을 보지 못합니다. 이것은 해킹처럼 보이지만 더 좋은 해결책이 있습니까?

+1

그것은 내가 같은 문제가있을 때 가지고 올 것을 기본적이다 :

자세히과 ++ ObjC에 대해 길게 이야기 팟 캐스트를 포함하는 정보에 더 링크,이 스레드를 참조하십시오. 하지만 ifdef에주의를 기울여 라. 비 -cpp 분기에 패딩을 삽입해야한다. 그렇지 않으면 컴파일러는 Foo 객체의 크기를 알 수 없습니다. 이것은 취약하지 않은 인스턴스 var 빌드에서 중단되지 않을 수도 있지만 이전 스타일의 대상에서는 확실히 문제입니다. –

+0

위에서 설명한 접근 방식을 복사했습니다. 꽤 멋지고 쉬운 것 같았지만, 다음에는 미친 메모리 손상 문제가 발생했습니다 : http://stackoverflow.com/questions/2458652/objective-c-insanity-simple-assignement-to-a-single-float-variable-results – morgancodes

답변

8

이것은 인터페이스/@ 프로토콜의 고전적인 사용법처럼 들립니다. API에 대한 objective-c 프로토콜을 정의한 다음 Objective-C++ 클래스를 사용하여 해당 프로토콜의 구현을 제공하십시오. 이 방법으로 클라이언트는 구현의 헤더가 아니라 프로토콜에 대해서만 알 필요가 있습니다. 그래서 프로토콜

//Extending the NSObject protocol gives the NSObject 
// protocol methods. If not all implementations are 
// descended from NSObject, skip this. 
@protocol IFoo <NSObject> 

// Foo methods here 
@end 

을 정의하고 수정 원래 Foo 선언을

@interface Foo : NSObject <IFoo> 
{ 
    id regularObjectiveCProperty; 
    CPPClass cppStuff; 
} 

@end 

클라이언트 코드를 입력 한 다음 id<IFoo> 작업 할 수 있으며 필요가없는 것입니다

@interface Foo : NSObject 
{ 
    id regularObjectiveCProperty; 
    CPPClass cppStuff; 

} 

@end 

원래의 구현을 제공 Objective-C++로 컴파일됩니다. 분명히 Foo의 인스턴스를 이러한 클라이언트에 전달할 수 있습니다.

+0

@interface Foo가 .h 파일에 있으면 obj-C++에 영향을 미치는 것을 막을 수 있습니까? @interface Foo가 .mm 파일에 있으면 어떻게 인스턴스를 만들 수 있습니까? – Eonil

+1

Foo.h를 가져 오는 모든 모듈은 Objective-C++로 컴파일해야하지만 클라이언트 코드는 IFoo를 사용하기 위해 IFoo 헤더 만 가져와야하므로 Objective-C 만 가능합니다. 이는 고전적인 종속성 관리 패턴입니다. 귀하의 예에서 –

+0

, 헤더를 가져 오지 않고 새로운 Foo를 인스턴스화하는 방법은 무엇입니까? 가장 먼저 떠오르게되는 것은 Objective C++ 팩토리 클래스입니다.이 클래스는 가져 오지 않고 C++ 헤더에 포함됩니다. 그것은 모두 매우 복잡해 보입니다. 또한이 방법이 있습니다 : http://stackoverflow.com/questions/2262011/adding-c-object-to-objective-c-class/2262395하지만 작동시키지 못했습니다 (http://stackoverflow.com 참조)./question/2463970/trouble-using-opaque-in-objective-c) – morgancodes

1

Objective C++을 모든 용도로 사용할 수없는 특별한 이유가 있습니까? 컴파일러를 소스로 컴파일하기 : Objective C++ (또는 .cpp 또는 .m에서 .mm으로 모든 소스 파일 이름 바꾸기). 그럼 당신은 자유롭게 어떤 문제가 거기 당신의 C++ 및 목적 C. 전체 응용 프로그램

에 확산하기 시작 ++

C를 혼용 할 수 있습니까? Objective C 코드가 일반적으로 C/Objective C 코드 만 수행하는 경우 C++로 컴파일되면 거의 영향을받지 않습니다. 상당한 크기 또는 속도 성능 문제는 없습니다.

단 두 가지 단점은 다음과 같습니다. 당신은 (아직) analyseC++에 정적 분석기를 사용할 수 없습니다. 일부 (상대적으로 이상한) C 코드는 C++에서 작동하지 않을 수 있습니다. 이는 제 3 자 C 코드를 사용할 때 가끔 문제가됩니다.

+0

유일한 문제는 C++에 익숙하지 않고 약간의 차이점이있을 것이라는 점입니다. 버그로 이어질 수 있습니다. 나는 C++이 정말로 필요한 클래스에만 캡슐화된다는 생각을 좋아합니다. 그러나 고맙습니다. 이것은 확실히 해결책입니다. – zoul

0

ObjectiveC++의 기억에서 생성자와 폐위 자의 C++ 객체에 대한 소멸자가 호출되지 않을 수도 있습니다.

3

최근에이 문제가 발생했습니다. 제 경우에는 프로토콜이 과도했습니다. C++ 객체가 된 데이터 액세스 객체에 대한 포인터를 유지해야했습니다.

내가 수행 한 작업은 void * 인스턴스 변수가있는 클래스를 선언하고 인스턴스 메서드에서 사용할 때이를 캐스팅했습니다.

이것은 약간 해킹이지만 개념적으로 Objective-C id 유형과 매우 비슷합니다. 이 클래스에 대해 두 개의 별도의 인스턴스 변수 레이아웃을 줄 것이다 인스턴스 변수를 밖으로 IFDEF 경우

0

는이

하지 않습니다. 절반의 경우에 객체에 할당 된 메모리가 너무 짧기 때문에 임의의 메모리 smashers를 얻을 수 있습니다. 대신 인스턴스 변수를 ifdefing의, 당신의 init/dealloc 방법은 새로운 호출에서 다음/객체를 생성, 삭제,

struct CPPClass; 

같은 유형을 전방 선언하고 바르에 대한 포인터를 가지고있다. 여러 개의 객체가있는 경우 모든 C++ ivars를 직접 보유한 구조체를 생성 한 다음 해당 구조체를 새로 작성/삭제할 수 있습니다. Can I separate C++ main function and classes from Objective-C and/or C routines at compile and link?

+0

C에서 구조체 타입은'CPPClass'가 아니라'struct CPPClass'로 참조되어야합니다. 그래서 구조체 타입도 변경해야합니다. – newacct

+0

ivar 선언에서 네, 잘 잡습니다. C++ struct Foo와 Foo는 같기 때문에 헤더에만 필요합니다. 일반적으로 클래스 이름 앞에 struct를 씁니다. 여기서는 독자적으로 언급 한 것처럼 별도의 struct 선언이 필요하지 않습니다. – uliwitness

관련 문제