C++ STL:vector实现

练习一发,主要是使用placement new在原始内存上创建对象。半路md面试电话来了,赶紧存档,看Java大法

#include <iostream>
#include <cstdlib>
#include <vector>
#include <algorithm>

using namespace std;

class Object {
public:
    static int count;
public:
    int current;
    int id;
    Object(int i) {
        id = i;
        current = count++;
        cout<<"object["<<id<<"] create : "<<current<<endl;
    }
    
    ~Object() {
        cout<<"object["<<id<<"] destroy: "<<current<<endl;
    }

    Object(const Object& obj) {
        current = count++;
        id = obj.id;
        cout<<"object["<<id<<"] copied : "<<current<<" old : "<<obj.current<<endl;
    }
};

int Object::count = 0;

template<class T>
class MyVector {
public:
    typedef T               value_type;
    typedef value_type*     pointer;
    typedef value_type*     iterator;
    typedef value_type&     reference;
    typedef size_t          size_type;
    typedef ptrdiff_t       difference_type;
    
private:
    iterator  start;
    iterator  finish;
    iterator  space_end;
public:
    MyVector() {
        start = NULL;
        space_end = NULL;
        finish = NULL;
    }
    
    size_type capacity() {return space_end - start;}
    size_type size() { return finish - start; }

    bool empty() { return start == finish; }
    iterator begin() {return start;}
    iterator end() {return finish;}
    
    reference operator[] (int idx) {return start[idx];}
    reference front() {return *start;}
    reference back() {return *(finish-1);}
    
    void clear() {

    }
    
    void pop_back() {
        if (start >= finish) {
            return;
        }
        finish--;
        finish->~T();
    }
    
    void push_back(const T& x) {
        if (finish < space_end) {
            // placement new
            new (finish) T(x);
            // adjust end pointer
            finish++;
        } else if (space_end == finish){
            // space not enough
            int olen = finish - start;
            int nlen = olen == 0 ? 1 : olen * 2;
            T* new_start = (T*) malloc(nlen * sizeof(T));
            T* new_finish = new_start;
            for (int i=0; i<olen; i++) {
                // copy old data to new space
                new (new_finish++) T(*(start + i));
            }
            // append pushed element
            new (new_finish++) T(x);

            // deconstruct old ones
            for (int i=0; i<olen; i++) {
                (start+i)->~T();
            }
            free(start);
            
            start = new_start;
            finish= new_finish;
            space_end = start + nlen;
        } else {
            // state invalid
            cerr<<"error"<<endl;
        }
    }
    
    ~MyVector() {
        for (T* s=start; s<finish; s++) {
            s->~T();
        }
        free(start);
    }
};

#define USE_ORG 0
int main() {

    long* a = NULL;
    long* b = a + 1;
    int n = (char*)b - (char*)a;
    
    cout<<n<<endl;
    
    
    
    int last_capacity =-1;
    Object::count = 0;
    
#if USE_ORG
    vector<Object> tmp;
#else
    MyVector<Object> tmp;
#endif

    for (int i=0; i<5; i++) {
        tmp.push_back(Object(i));
        if (last_capacity != tmp.capacity()) {
            cout<<"======last cap:"<<last_capacity<<" new capacity:"<<tmp.capacity()<<endl;
            last_capacity = tmp.capacity();
        }

        cout<<"

"<<endl;
    }

    MyVector<int> ints;
    ints.push_back(2);
    ints.push_back(3);
    ints.push_back(1);
    
    sort(ints.begin(), ints.end());
    
    for (int i:ints) {
        cout<<i<<endl;
    }
    
    system("pause");
    return 0;
}
原文地址:https://www.cnblogs.com/lailailai/p/4342775.html