vector从获取到某块存储区开始
就好像一直进行猜测
在放入的对象还没有超出初始存储块所能装载的对象数目的时候
所有的操作都进行得飞快
观察在填充一个vector时发生的事情 有一个Noisy类
打印出其有关创建 析构 赋值以及拷贝构造的信息
//: C07:Noisy.h
// From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison.
// (c) 1995-2004 MindView, Inc. All Rights Reserved.
// See source code use permissions stated in the file 'License.txt',
// distributed with the code package available at www.MindView.net.
// A class to track various object activities.
#ifndef NOISY_H
#define NOISY_H
#include <iostream>
using std::endl;
using std::cout;
using std::ostream;
class Noisy {
static long create, assign, copycons, destroy;
long id;
public:
Noisy() : id(create++) {
cout << "d[" << id << "]" << endl;
}
Noisy(const Noisy& rv) : id(rv.id) {
cout << "c[" << id << "]" << endl;
++copycons;
}
Noisy& operator=(const Noisy& rv) {
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() {
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(); }
};
// A Singleton. Will automatically report the
// statistics as the program terminates:
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;
}
};
#endif // NOISY_H ///:~
//: C07:Noisy.cpp {O}
// From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison.
// (c) 1995-2004 MindView, Inc. All Rights Reserved.
// See source code use permissions stated in the file 'License.txt',
// distributed with the code package available at www.MindView.net.
#include "Noisy.h"
long Noisy::create = 0, Noisy::assign = 0,
Noisy::copycons = 0, Noisy::destroy = 0;
NoisyReport NoisyReport::nr;
///:~
每个Noisy对象都有其标识符
并且设置一些静态static变量用来跟踪所有的创建
赋值 拷贝构造和析构操作
NoisyReport是一个单件对象
因为仅仅要在程序结束时打印一个报告
使用Noisy.h 演示vector分配的存储区溢出的情形
//: C07:VectorOverflow.cpp {-bor}
// From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison.
// (c) 1995-2004 MindView, Inc. All Rights Reserved.
// See source code use permissions stated in the file 'License.txt',
// distributed with the code package available at www.MindView.net.
// Shows the copy-construction and destruction
// that occurs when a vector must reallocate.
//{L} Noisy
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
#include "Noisy.h"
using namespace std;
int main(int argc, char* argv[]) {
int size = 1000;
if(argc >= 2) size = atoi(argv[1]);
vector<Noisy> vn;
Noisy n;
for(int i = 0; i < size; i++)
vn.push_back(n);
cout << "\n cleaning up " << endl;
getchar();
} ///:~
输出
d[0]
c[0]
c[0]
~[0]
c[0]
c[0]
c[0]
~[0]
~[0]
c[0]
c[0]
c[0]
c[0]
~[0]
~[0]
~[0]
c[0]
c[0]
c[0]
c[0]
c[0]
~[0]
~[0]
~[0]
~[0]
c[0]
c[0]
c[0]
c[0]
c[0]
c[0]
c[0]
c[0]
~[0]
~[0]
~[0]
~[0]
~[0]
~[0]
c[0]
c[0]
c[0]
c[0]
c[0]
c[0]
c[0]
c[0]
随机出现 我用ctrl+c终止输出
运行该程序 会看到一个默认构造函数调用 为n
然后是很多的拷贝构造函数的调用
接下来看到新函数的调用
然后又是很多拷贝函数的调用
当vector用光了为线性数组分配的空间字节时
vector必须获得一块更大的存储空间并且将原来的内容全部移过去
先拷贝再销毁原来的对象
vector的内存重分配会更糟
因为vector在一个优美间接的数组中保存它的对象
被vector使用的迭代器可以是简单的指针
//: C07:VectorCoreDump.cpp
// From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison.
// (c) 1995-2004 MindView, Inc. All Rights Reserved.
// See source code use permissions stated in the file 'License.txt',
// distributed with the code package available at www.MindView.net.
// Invalidating an iterator.
#include <iterator>
#include <iostream>
#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;
// Force it to move memory (could also just add
// enough objects):
vi.resize(vi.capacity() + 1);
// Now i points to wrong memory:
*i = 48; // Access violation
copy(vi.begin(), vi.end(), out); // No change to vi[0]
getchar();
} ///:~
输出 后跳出一个异常对话框
47 0 0 0 0 0 0 0 0 0
迭代器无效 iterator invalidation
某种操作引发设计容器底层数据的内部变化
在变化之前有效的那些迭代器可能后来不再有效