2009-03-10 1 views
3

선언 생성자 :앞으로 포인터 - 투 - 구조체 C++에서이 같은 선언이있는 제 3 자 라이브러리를 사용하고

class Foo 
{ 
    Foo(HandleType h); 
} 

이 HandleType를 정의하는 헤더를 포함없이. 일반적으로, 나는 단지 그런 타입을 선언하고 싶지만, 이것에 대한 구문을 이해할 수는 없다. 나는 다음과 같이 말하고 싶습니다 :

struct *HandleType; 

그러나 GCC의 "예상 식별자는 * 전"입니다. 내가 볼 수있는 유일한 해결책은 내 수업을 다음과 같이 작성하는 것입니다.

struct __INTERNAL_DATA; 
class Foo 
{ 
    Foo(__INTERNAL_DATA *h); 
} 

하지만 이것은 라이브러리의 내부 세부 정보를 사용합니다. 즉, 구현 세부 사항 인 __INTERNAL_DATA라는 이름을 사용합니다.

__INTERNAL_DATA (라이브러리 구현의 일부)를 사용하지 않고 HandleType (공용 API의 일부)을 전달 선언 할 수 있어야합니다. 누구나 알 수 있습니까?

편집 : 내가 찾고있는 것에 대한 자세한 내용을 추가했습니다.

답변

4

업데이트 :

나는 푸의 구현 .CPP에서 그것을 사용하고,하지만 난 푸 내 헤더 .H에 포함하지 않도록합니다. 어쩌면 나는 너무 성급한가? :)

예 예 : :) 앞으로 선언을 진행하십시오.

HandleType이 인터페이스의 일부인 경우이를 선언하는 헤더가 있어야합니다. 해당 헤더를 사용하십시오.

당신의 문제는 여전히 애매합니다. 당신은 할 수없는 일로부터 보호하려고 노력하고 있습니다.

당신은 당신의 클라이언트 라이브러리에 다음 줄을 추가 할 수 있습니다 : 이름/구조를 변경하는 경우

typedef struct INTERNAL_DATA *HandleType; 

하지만, 일부 주조 불결함에 대한에있을 수 있습니다.

시도 템플릿 :

template <class T> 
class Foo 
{ 
    Foo(T h); 
}; 

앞으로 선언이 괜찮습니다. 포인터 나 참조를 사용하려면 범위에 클래스 (__INTERNAL_DATA) 선언 만 있으면됩니다. 그러나 멤버 함수 또는 개체를 사용하려는 경우 헤더를 포함해야합니다.

+0

그렇다면 변경하거나 완전히 제거 할 수있는 이름 인 __INTERNAL_DATA를 forward-declare해야합니다. (이후 라이브러리의 구현 세부 사항입니다.) –

+0

그래서 당신이 아는 모든 HandleType 수 있습니다. – dirkgently

+0

요구 사항이 명확하지 않아 어쩌면 세부 사항을 더 추가 할 수 있습니다. – dirkgently

1
typedef struct {} __INTERNAL_DATA, *HandleType; 

이렇게 정의 된 경우 (모두 한 줄로 표시) __INTERNAL DATA는 HandleType과 마찬가지로 공용 인터페이스의 일부입니다.

그러나 실제로는 __INTERNAL_DATA이 존재하지 않는다고 생각합니다.아마도 HandleType은 실제로 (내부적으로) int입니다. 이 이상한 정의는 int와 같은 크기가되도록 distinct를 정의하는 방법 일 뿐이지 만, HandleType을 전달해야하는 곳의 int를 전달하려고하면 컴파일러가 오류를 발생시킵니다. 라이브러리 공급 업체는이를 "int"또는 "void *"로 쉽게 정의 할 수 있습니다. 그러나 이렇게하면 형식 검사가 수행됩니다.

따라서 __INTERNAL_DATA은 규칙 일 뿐이므로 변경하지 않습니다.


UPDATE : 위의 정신 트림의 조금 ... OK, __INTERNAL_DATA 확실히 존재하지 않는했다. 우리는 이것을 사실로 알고 있습니다. 왜냐하면 우리는 을 볼 수 있습니다.은 빈 구조체로 정의되어 있습니다. 제 3 자 라이브러리가 "C"외부 링키지 (이름 변경 없음)를 사용하는 것으로 추측합니다.이 경우 은 typedef를 복사하기 만하면됩니다.

라이브러리 자체 내에서 HandleType 과 완전히 다른 정의입니다. 아마 int, 아마도 "struct MyStruct {.......} *".

1

유형이 제 3 자 라이브러리에 있으면 순방향 선언 (헤더 변경으로 인한 재 구축 격리)의 큰 이점이 효과적으로 상실됩니다.

컴파일 시간이 걱정되는 경우 (상당히 큰 헤더), 미리 컴파일 된 헤더에 배치하거나 라이브러리의 관련 헤더를 포함시킬 수 있습니다.

예. 당신은 여전히 ​​것,

// foo.h 
class Foo 
{ 
    public: 
    template<typename T>Foo(T* h) { /* body of constructor */ } 
}; 

마음을 : 많은 라이브러리 헤더 나는 당신이려고하고 있지만, 다음은 실제 헤더 파일을 포함하지 않고 작동 무엇을 아주 확실하지 않다

// library.h 
#include "Library/Something.h" 
#include "Library/SomethingElse.h" 
1

처럼 생성자 본문 내에서 __INTERNAL_DATA의 public 멤버에 액세스해야합니다.

편집 :은 James Curran이 지적한 바와 같이, __INTERNAL_DATA 구조에는 구성원이 없으므로 위에서와 같이 문제없이 사용할 수 있습니다.

+0

typedef를 자세히 확인하십시오 ... __INTERNAL_DATA에는 공개 (또는 개인) 멤버가 없습니다 .... –

+0

나는 그 질문을 단순하게 유지하기위한 예제 구조라고 가정했습니다. –

+0

...하지만 귀하의 요점을 참조하십시오. 답변이 업데이트되었습니다. –

1

발신자에게 _INTERNAL_DATA를 공개하고 싶지 않다면 유일한 선택은 입니다. typedef void * HandleType; 그런 다음 라이브러리 내부에서 * HandleType의 전체 구현을 변경하는 것을 포함하여 원하는 모든 작업을 수행 할 수 있습니다.

실제 데이터에 액세스하는 도우미 함수를 만들면됩니다.

inline _INTERNAL_DATA* Impl(HandleType h) { 
    return static_cast<_INTERNAL_DATA*>(h); 
} 
관련 문제