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;
}