2011-10-04 3 views
3

STL을 배우기 전에 저에게 작성된 범용 라이브러리를 다시 작성하고 있습니다. 그것은 C 스타일 배열을 항상 사용합니다. 다음stl 컨테이너의 크기 처리

unsigned short maxbuffersize; 
unsigned short buffersize; 
std::vector<T> buffer; 

: 그리고 내가 한

unsigned short maxbuffersize; // Maximum possible size of the buffer. Can be set by user. 
unsigned short buffersize; // Current size of the buffer. 
T *buffer; // The buffer itself. 

가장 먼저하는 일이 이런 식으로 코드를 변경했다 :

typedef unsigned short BufferSize; 
BufferSize maxbuffersize; 
BufferSize buffersize; 
std::vector<T> buffer; 

을 그리고 나는 많은 장소에서 이런 코드가있다 내가 아주 나쁜 일을하고있는 것처럼 느껴졌고 제 코딩 스타일을 재고해야합니다. 처음에는 BufferSize가 유형에 대해 매우 나쁜 이름처럼 보였지만 모든 종류의 이상한 질문이 나타났습니다. 크기 유형의 이름은 어떻게 지정합니까? 내 형식을 사용하거나 std::vector<T>::size_type에서 상속해야합니까? 컨테이너의 크기를 캐시하거나 size()을 계속 사용해야합니까? 사용자가 컨테이너의 최대 크기를 수동으로 설정할 수 있도록 허용해야하고 그렇지 않은 경우 오버플로를 확인하려면 어떻게해야합니까?

나는 하나의 크기에 맞는 방법을 사용할 수 없다는 것을 알고 있으므로 다른 코더 및 프레임 워크 공급 업체가 사용하는 정책을 듣고 싶습니다. 제가 작업하고있는 라이브러리는 크로스 플랫폼 범용이며 퍼블릭 도메인으로 풀려나 수십 년 동안 사용되기위한 것입니다. 감사.

+0

퍼블릭 도메인으로 공개하려고하므로 프로그램에 약간의 플러그를 주어야한다고 생각합니다. – Tom

+0

일부 제한 사항 (예 : 단 하나의 인스턴스)이 제거 된 [소스 엔진 콘솔] (http://developer.valvesoftware.com/wiki/Console)의 복제본입니다. – Lyberta

+0

에이스, 인터넷에 리포지토리 (예 : github)를 설치 한 경우 - 링크 게시 – Tom

답변

12

기본 선택은 buffersizemaxbuffersize을 모두 없애고 전체적으로 buffer.size()buffer.capacity()을 사용해야한다고 생각합니다.

프로필러 실행의 하드 데이터로 뒷받침되는 특별한 이유가없는 한 크기 의 캐싱을 권장하지 않습니다. 캐싱은 캐시를 실제와 동기화 할 수있는 추가 복잡성과 잠재적 가능성을 유발합니다.

마지막으로 범위 검사가 필요하다고 생각되는 곳에서는 buffer.at(i)을 사용할 수 있습니다. i가 범위를 벗어나는 경우 예외가 throw됩니다.

+0

'std :: vector '의 크기를 버퍼링하는 것은 완전히 바보입니다. 이는 일정한 성능 (즉, 요소의 수에 관계없이)을 보장하기 때문입니다. 이것은 다른 시퀀스 컨테이너에 대해서도 마찬가지입니다 ('std :: array','std :: string','std :: valarray' 포함) – rubenvb

+1

@rubenvb 정말요? 'for (size_t i = 0; i Tom

+0

명명 규칙은 어떻게됩니까? 나는 BufferSizeType이 좋다고 생각하지만, 인덱스가 전달된다는 사실은 사용자에게 불투명하고 나는 그것을 커버 할 수있는 좋은 방법을 모른다. – Lyberta

2

일반적으로 데이터에 액세스 할 때 이터레이터를 사용하는 것이 좋습니다. 이렇게하면 컨테이너의 크기를 명시 적으로 호출하지 않는 경우가 있습니다. 이것은 또한 std::vector을 사용하지 못하도록합니다. 예를 들어 나중에 std::list으로 변경하면 나중에 사용자의 필요에 더 잘 맞는다는 것을 알게됩니다.

반복자를 사용하면 일반적으로 vector.size()의 필요성이 크게 줄어 듭니다. (필요하다면 aix가 말한 것처럼 buffer.size()buffer.capacity()을 사용하십시오).

:

typedef unsigned short BufferSize; 
BufferSize maxbuffersize; 
BufferSize buffersize; 
std::vector<T> buffer; 
for(unsigned short i = 0; i< maxbuffersize;++i) 
{ 
    //do something with buffer[i]; 
} 

조금 청소기이다

struct do_something 
{ 
    void operator()(const T& t) 
    { 
    //do something with buffer[i] 
    } 
}; 
std::vector<T> buffer(maxbuffersize); 
std::for_each(buffer.begin(), buffer.end(), do_something()); 

된다.

0

크기를 유지하는 것은 구조체에 유용하지만 크기가 최종 인덱스 + 1이 될 것이므로 배열/벡터에 대해서는 약간 중복됩니다.과거를 뛰어 다니는 것에 대해 걱정이된다면, 언급 된 반복자 접근법은 이것을 해결할 수있을뿐만 아니라 비교 가능한 크기와 관련된 대부분의 다른 문제를 해결할 것입니다.

다른 플랫폼 및 컴파일러에 맞게 설정하는 API로 헤더에 모든 유형과 크기를 정의하는 것이 꽤 표준입니다 ... LONG, ULONG, DWORD 등의 정의가있는 창을보세요. "C"관례는 MYAPI_SIZETYPE와 같은 고유 한 이름이나 머리 글자로 시작하는 것입니다. 말도되지만 교차 플랫폼 혼동이나 컴파일러 문제는 피할 수 있습니다.

+0

모두 넣었습니다. 내 타입을 내 네임 스페이스에 넣고 이름 충돌을 피하기 위해'using'을 사용하지 마십시오. – Lyberta

관련 문제