2010-02-01 6 views
1

요소 배열을 보유하고있는 클래스가 있는데이 요소에 GetSize 멤버 함수를 제공하려고합니다. 그러나 그 함수에 어떤 리턴 타입을 주어야합니까?Pimpl 관용구 : 구현을 알 수없는 경우 사용할 size_type은 무엇입니까?

저는 pimpl 관용구를 사용하고 있습니다. 따라서 헤더 파일에서 요소가 요소를 저장하는 데 어떤 구현을 사용할지 알 수 없습니다. 그래서 난 그냥 예를 들어, std::vector<T>::size_type 말할 수 없다 :

class FooImpl; 

class Foo { 
    FooImpl* impl_; 
public: 
    TYPE GetSize(); // what TYPE?? 
}; 
+0

합니다.두 번째 부분에서는 "구현 요소가 요소를 저장하는 데 사용되는 것이 알려지지 않았습니다"라고 말합니다. 그래서, 귀하의 컨테이너가 C++ - 배열 기반 구현으로 제한되어 있습니까? 실제 구현이 데이터를 저장하기 위해 목록이나 트리 (또는 다른 것)를 사용하는 것이 가능한가? 아니면 항상 물리적 배열로되어 있습니까? – AnT

+0

@AndreyT : 구현은 C 배열, 고유 한 사용자 정의 배열, std :: vector 또는 무엇이든 원하는대로 사용할 수 있습니다. – Frank

+0

@dehmann : 글쎄, 문제는 이것이 물리적 인 배열, 즉 연속적인 메모리 블록인지 아니면 개념적 배열 (예 : 연관 배열)인지에 관한 문제입니다. 예를 들어'std :: map' 컨테이너는 C++에서 연관 배열을 구현합니다. 귀하의 경우에 사용할 수 있습니까? 또한 연결 목록을 사용하여 개념 배열을 구현할 수도 있습니다 (비효율적 임에도 불구하고). 귀하의 경우 가능합니까? – AnT

답변

1

클라이언트 코드가 Foo (pimpl 관용구의 목적) 만 볼 수 있다면 구체적인 구현에서 특정 size_type을 정의 할 필요가 없습니다. 어쨌든 클라이언트는 볼 수 없거나 액세스 할 수 없습니다. 표준 컨테이너는 런타임시 구현 숨기기 메소드를 사용하려고 시도하는 동안 소위 "컴파일 타임 다형성"으로 빌드되기 때문에이를 수행 할 수 있습니다.

상황에 따라 유일한 선택은 "가능한 모든 구현에 충분해야합니다"(예 : unsigned long과 같은) 인 정수 유형을 선택하고 그대로 사용하는 것입니다.

uintptr_t 유형을 구현에 사용할 수있는 경우 (C99에서는 표준화되었지만 C++에서는 표준화되지 않음) 또 다른 가능성이 있습니다. 이 정수형은 프로그램에서 사용할 수있는 전체 저장소 주소 범위를 포함하므로 모든 메모리 내부 컨테이너의 크기를 나타내는 데 충분합니다. 다른 포스터에서는 종종 동일한 논리를 사용하지만 여기에서 사용할 적절한 유형은 size_t이라는 결론에 도달하지 못합니다. 일반적으로 컨테이너는 물리적 어레이를 기반으로하는 경우 size_t이 작동합니다. 그러나 컨테이너가 항상 배열 기반이 아닌 경우 size_t의 범위는 일반적으로 비 연속 (배열 기반이 아닌) 컨테이너의 최대 크기보다 작기 때문에 여기에서 사용할 올바른 유형의 원격 유형이 아닙니다.

그러나 어떤 경우 든 표준 컨테이너에서 수행되는 것처럼 typedef 이름 뒤에 숨기는 것이 좋습니다.

0

말하자면 size_type 년대는 일반적으로 (등 오래 오래 오래 대 대 짧은) 정수 유형을 숨기는 데 사용된다. 자신 만의 Foo::size_type을 정의하십시오.

1

C++의 크기에 대한 일반적인 유형은 size_t입니다. 나는 그것을 사용할 것이다.

나는 비 기술적 인 의미에서 일반적인 의미입니다. 이것은 템플릿과 관련이 없습니다. 많은 토론 후 When should I use std::size_t?

편집

, 나는 약간 내 대답을 수정거야 :

이가 전에 온 것 같은데.

size_t가 포인터만큼 넓은 경우 size_t를 사용하십시오. 그렇지 않은 경우에는 포인터와 동일한 너비의 부호없는 정수를 사용하십시오.

+0

OP의 질문에서 "크기"는 실제로 크기가 아니라 "컨테이너 요소 수"입니다. 이해합니다. 'size_t '는 * object size *에 대한 제네릭 타입이며 일반적으로 컨테이너 요소 수를 다시 표시하는 데 사용할 수 없습니다. 컨테이너가 배열 기반'size_t' 인 경우이 경우에만 작동합니다. – AnT

+2

왜 안되니? 그의 경우에는 배열을 보유하고 배열은'size_t '로 제한되어 있습니다. 즉, size_t/sizeof (element_type) 요소를 가질 수 있습니다. 항상 jalf

+1

@jalf : I OP에서 "배열"이라는 용어가 물리적 C++ 배열을 기반으로하는 것이 아니라 "선형 contaner"를 의미한다고 가정합니다. OP는 명시 적으로 나중에 "구현 요소가 요소를 저장하는 데 사용하는 것이 알려지지 않았습니다"라고 명시합니다. – AnT

0

당신은 STL의 리드를 따라 FooImpl에 의존 size_typetypedef 만들 수 있습니다 : 당신이 "요소의 배열"에 대해 이야기하고 질문의 첫 번째 부분에서는

template<typename T> class s_type { 
    public: 
    typedef size_t type; // good default 
}; 

class FooImpl; 

// I'm only doing this specialization to show how it's done 
// not because I think it's needed. In general I'd use size_t. 
template<> class s_type<FooImpl> { 
    public: 
    typedef uintptr_t type; 
}; 

class Foo { 
    FooImpl* impl_; 

    public: 
    typedef size_type s_type<FooImpl>::type; 
    size_type GetSize(); 
}; 
+0

정확하게 이해하면 유사하지만 별개의 문제가 해결됩니다. –

+0

질문은 "어떤 반환 유형을 부여해야합니까?" 끈적한 부분은 반환 유형이 FooImpl의 구현에 의존한다는 것입니다. 이 솔루션은 FooImpl의 구현에 의존하는 반환 유형을 제공합니다. 이것은 OP와 어떻게 다른 점입니까? –

관련 문제