2012-04-18 1 views
0
#ifndef VECTOR 
#define VECTOR 

template<typename T> 
struct vector 
{ 
private: 
    T *buffer; 
    unsigned long sz; 
    unsigned long cap; 
public: 
    typedef T value_type; 
    typedef value_type& reference; 
    typedef const reference const_reference; 
    typedef value_type* pointer; 
    typedef const pointer const_pointer; 
    typedef T* iterator; 
    typedef const T* const_iterator; 
    typedef unsigned long size_type; 
    typedef ptrdiff_t difference_type; 

    vector() : buffer(new int[10]), sz(0), cap(10) {} 
    vector(size_t s) : buffer(new int[sz]), sz(s), cap(s){} 
    vector(size_t s, const T& initial) : buffer(new int[sz]), sz(s), cap(s) { for(size_t i = 0; i < sz; i++) buffer[i] = initial; } 
    template<typename container, typename It> 
    vector(typename container::It beg, typename container::It end) 
    { 
     It iter(beg); 
     sz = ptrdiff_t(beg-end); 
     cap = sz; 

     for(int i = 0; i < sz; i++) 
     { 
      buffer[i] = iter++; 
     } 
    } 
    ~vector() {delete [] buffer;} 

    iterator begin() {return buffer;} 
    const_iterator begin() const {return buffer;} 

    iterator end() {return buffer+sz;} 
    const_iterator end() const {return buffer+sz;} 

    void reserve(size_t newCap) 
    { 
     if(newCap <= cap) return; 
     T *oldBuffer = buffer; 

     buffer = new T[newCap]; 

     for(int i = 0; i < cap; i++) 
     { 
      buffer[i] = oldBuffer[i]; 
     } 

     cap = newCap; 
     delete [] oldBuffer; 
    } 
    void resize(size_t newSz, const T& initial = T()) 
    { 
     if(newSz > cap) 
      reserve((newSz*2+1)%(max_size()+1)); 
     if(newSz > sz) 
     { 
      for(int i = sz; i < newSz; i++) 
       buffer[i] = initial; 
     } 
     sz = newSz; 
    } 
    size_t size() const {return sz;} 
    size_t capacity() const {return cap;} 
    bool empty() const {return sz == 0;} 
    size_t max_size() const {return 1073741823;} 
    void push_back(T toP) 
    { 
     if(sz >= cap) 
      reserve((cap*2+1)%(max_size()+1)); 
     buffer[sz++] = toP; 
    } 
    T pop_back() 
    { 
     T ret = buffer[sz-1]; 
     buffer[sz-1] = T(); 
     sz--; 
     return ret; 
    } 
    reference front() { return buffer[0]; } 
    const_reference front() const { return buffer[0]; } 

    reference back() { return buffer[sz-1]; } 
    const_reference back() const { return buffer[sz-1]; } 

    T& operator[](size_t index) {if(index >= sz) throw std::out_of_range("out_of_rane"); return buffer[index]; } 
    const T& operator[] (size_t index) const {if(index >= sz) throw std::out_of_range("out_of_rane"); return buffer[index];} 

    T& at(size_t index) { return (*this)[index]; } 
    const T& at(size_t index) const { return (*this)[index]; } 
}; 

#endif 

이것은 벡터 클래스의 구현입니다. 이것은 T 형의 동적 배열을 사용하는데, 이것은 reserve() 함수로 커집니다. 할당 자 클래스를 사용하여 구현 한 경우 어떻게 될까요? (전체 벡터 클래스뿐 아니라 예비 기능)할당 자 클래스를 사용하는 벡터 구현

template<class T, class Allocator = allocator<T> > 

이것은 파일 stl_vector.h

+0

대안이 무엇인지 명시하지 않고 더 빠르고 효율적인 버전을 묻습니다. 하나의 옵션 ('template >')을주었습니다. 나는 그 중 하나가 당신이 부여한 대안 중에서 가장 빠른 것으로 가정 할 것이다 ... – Grizzly

+4

밑줄을 두 개 포함하거나, 밑줄 뒤에 대문자를 붙이는 식별자 (매크로 이름 포함)는 구현을 위해 예약되어있다. 자신의 코드에서 사용하지 마십시오. –

+0

감사합니다. 기억합니다. –

답변

0

STL과의 기본 할당이 효율적으로 작업을 할 수있는 새 운영자를 호출에 같은 모습입니다 . 그래서 저는 그것이 많이 바뀌지 않을 것이라고 생각합니다. 그러나 코드를 보면 성능 ​​질문에 대한 충분한 대답을 얻을 수 없습니다. 대신 두 가지 버전을 구현하고 몇 가지 일반적인 테스트 데이터로 측정해야합니다.