通用容器3_vector

1,vector特点:
(1)将内容放在一段连续的存储区域,索引和迭代操作非常的快.
(2)如果当前存储空间不够,需要重新分配一块更大的区域,将原来的对象拷贝到新的存储区,析构原来的对象,释放原来的内存.
Allocating a new, bigger piece of storage.
Copying all the objects from the old storage to the new (using the copy-constructor).
Destroying all the old objects (the destructor is called for each one).
Releasing the old memory.
(3)上述操作代价太大,最好预先知道需要多少个对象,然后使用reserve()预先分配大小,这样就避免了所有的拷贝和析构.
2,实例代码:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
using namespace std;

class Noisy
{
    static long create, assign, copycons, destroy;
    long id;
public:
    Noisy() : id(create++) //create:记录构造函数执行的次数
    {
        cout << "d[" << id << "]" << endl;
    }
    Noisy(const Noisy& rv) : id(rv.id) //copycons:记录拷贝函数执行的次数.
    {
        cout << "c[" << id << "]" << endl;
        ++copycons;
    }
    Noisy& operator=(const Noisy& rv) //assign:记录赋值操作执行的次数.
    {
        cout << "(" << id << ")=[" << rv.id << "]" << endl;
        id = rv.id;
        ++assign;
        return *this;
    }
    //容器对象,必须提供比较操作符
    friend bool operator<(const Noisy& lv, const Noisy& rv)
    {
        return lv.id < rv.id;
    }
    friend bool operator==(const Noisy& lv,const Noisy& rv)
    {
        return lv.id == rv.id;
    }
    ~Noisy() //destroy:记录析构函数调用的次数
    {
        cout << "~[" << id << "]" << endl;
        ++destroy;
    }
    friend ostream& operator<<(ostream& os, const Noisy& n)
    {
        return os << n.id;
    }
    friend class NoisyReport;
};

struct NoisyGen
{
    Noisy operator()()
    {
        return Noisy();
    }
};

//单件类,报告类的统计信息.
class NoisyReport
{
    static NoisyReport nr;
    NoisyReport() {} // Private constructor
    NoisyReport & operator=(NoisyReport &);  // Disallowed
    NoisyReport(const NoisyReport&);         // Disallowed
public:
    ~NoisyReport()
    {
        cout << "\n-------------------\n"
             << "Noisy creations: " << Noisy::create
             << "\nCopy-Constructions: " << Noisy::copycons
             << "\nAssignments: " << Noisy::assign
             << "\nDestructions: " << Noisy::destroy << endl;
    }
};
long Noisy::create = 0, Noisy::assign = 0,Noisy::copycons = 0, Noisy::destroy = 0;
NoisyReport NoisyReport::nr;

int main()
{
    freopen("main.txt","w",stdout);
    int size = 1000;
    vector<Noisy> vn;
    //vn.reserve(1200);  //有无差距很大.
    Noisy n;
    for(int i = 0; i < size; i++)
        vn.push_back(n);
    cout << "\n cleaning up"<< endl;
    return 0;
}

3,vector的内存重分配可能带来的问题:
实例代码:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
using namespace std;

int main()
{
    vector<int> vi(10, 0);
    ostream_iterator<int> out(cout, " ");
    vector<int>::iterator i = vi.begin();
    *i = 47;
    copy(vi.begin(), vi.end(), out);
    cout << endl;

    //强迫重新分配内存
    vi.resize(vi.capacity() + 1);
    *i = 48;  //这是i是之前的开头,不是现在的了.
    copy(vi.begin(), vi.end(), out); // No change to vi[0]
    return 0;
}

4,使用vector最有效的条件:
(1)You reserve( ) the correct amount of storage at the beginning so the vector never has to reallocate.
(2)You only add and remove elements from the back end.

5,下列代码指出了对vector进行插入和删除操作时,需要的额外代价.
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
using namespace std;

class Noisy
{
    static long create, assign, copycons, destroy;
    long id;
public:
    Noisy() : id(create++) //create:记录构造函数执行的次数
    {
        cout << "d[" << id << "]" << endl;
    }
    Noisy(const Noisy& rv) : id(rv.id) //copycons:记录拷贝函数执行的次数.
    {
        cout << "c[" << id << "]" << endl;
        ++copycons;
    }
    Noisy& operator=(const Noisy& rv) //assign:记录赋值操作执行的次数.
    {
        cout << "(" << id << ")=[" << rv.id << "]" << endl;
        id = rv.id;
        ++assign;
        return *this;
    }
    //容器对象,必须提供比较操作符
    friend bool operator<(const Noisy& lv, const Noisy& rv)
    {
        return lv.id < rv.id;
    }
    friend bool operator==(const Noisy& lv,const Noisy& rv)
    {
        return lv.id == rv.id;
    }
    ~Noisy() //destroy:记录析构函数调用的次数
    {
        cout << "~[" << id << "]" << endl;
        ++destroy;
    }
    friend ostream& operator<<(ostream& os, const Noisy& n)
    {
        return os << n.id;
    }
    friend class NoisyReport;
};

struct NoisyGen
{
    Noisy operator()()
    {
        return Noisy();
    }
};

//单件类,报告类的统计信息.
class NoisyReport
{
    static NoisyReport nr;
    NoisyReport() {} // Private constructor
    NoisyReport & operator=(NoisyReport &);  // Disallowed
    NoisyReport(const NoisyReport&);         // Disallowed
public:
    ~NoisyReport()
    {
        cout << "\n-------------------\n"
             << "Noisy creations: " << Noisy::create
             << "\nCopy-Constructions: " << Noisy::copycons
             << "\nAssignments: " << Noisy::assign
             << "\nDestructions: " << Noisy::destroy << endl;
    }
};
long Noisy::create = 0, Noisy::assign = 0,Noisy::copycons = 0, Noisy::destroy = 0;
NoisyReport NoisyReport::nr;

int main()
{
    vector<Noisy> v;
    v.reserve(11);
    cout << "11 spaces have been reserved" << endl;
    //先构造,然后拷贝到容器,最后析构构造的对象.
    generate_n(back_inserter(v), 10, NoisyGen());

    ostream_iterator<Noisy> out(cout, " ");
    copy(v.begin(), v.end(), out);
    cout<<endl;

    cout << "Inserting an element:" << endl;
    vector<Noisy>::iterator it =v.begin() + v.size() / 2; // Middle
    //由于空间足够,插入后面的元素依次执行赋值操作.
    //最后一个元素执行复制操作.
    //新的构造对象[10]先拷贝,放入容器,然后赋值给位置的元素,所以会析构两次.
    v.insert(it, Noisy());
    copy(v.begin(), v.end(), out);
    cout << endl;

    cout << "\nErasing an element:" << endl;
    //后面的元素一次赋值给前一个元素,最后一个元素析构.
    it = v.begin() + v.size() / 2;
    v.erase(it);
    copy(v.begin(), v.end(), out);
    cout << endl;

    return 0;
}


你可能感兴趣的:(OS,UP)