Effective STL 中文版学习记录
条款4 判断容器是否为空 使用empty而不是size().size()操作在实现上不是一个时间常数操作条款5 尽量使用区间成员函数代替它们的单元素兄弟.STL实现中,区间范围显示比单个循环操作更优化
条款7:当使用new得指针的容器时,记得在销毁容器前delete那些指针
vc2008下 运行代码 可以看到 该程序内存不断增加
// 1111111.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h" #include <vector> #include <windows.h> using namespace std; void DoSomethingV1() { vector<int*> pivec; //创建一个int指针的容器 for(int i = 0; i < 9;++i) { int* p = new(int); *p = i; pivec.push_back(p); } // 函数结束时候 容器在生存域外 则销毁 // 但是指针指向内容未销毁 内存泄露 } int _tmain(int argc, _TCHAR* argv[]) { while(1) { Sleep(1); DoSomethingV1(); } return 0; }
我们可以使用在某个使用完容器后的环节自行循环删除指针内容
void DoSomethingV2() { vector<int*> pivec; //创建一个int指针的容器 for(int i = 0; i < 9;++i) { int* p = new(int); *p = i; pivec.push_back(p); } // 函数结束时候 销毁指针内容 for (vector<int*>::iterator i = pivec.begin(); i != pivec.end(); ++i) { delete *i; } }
但是这个代码不是异常安全的
还有个解决办法就是 使用智能指针 BOOST的shared_ptr
#include <vector> #include <windows.h> #include <boost/smart_ptr.hpp> using namespace std; void DoSomethingV3() { typedef boost::shared_ptr<int> SPI; //SPi = "shared_ptr vector<SPI> vspi; for(int i = 0; i < 9;++i) { vspi.push_back(SPI (new int(i)) ); } }
条款8:永不建立auto_ptr的容器
auto_ptr似乎已经在C++ 11 中废弃
条款8:永不建立auto_ptr的容器
auto_ptr似乎已经在C++ 11 中废弃
条款9:在删除选项中仔细选择
不同的容器使用不同的方法
连续内存容器(vector、deque或string) 使用erase-remove惯用
c.erase(remove(c.begin(), c.end(), 22),c.end());
list容器仅仅使用remove方法
c.erase(2);
另外 如果在容器遍历循环中使用了erase。由于该方法的实现,必须根据是否进行擦除erase来区别处理遍历的迭代器
for (SeqContainer<int>::iterator i = c.begin(); i != c.end();)
{
if (badValue(*i))
{
cerr<< "Erasing " << *i << ‘\n‘;
i = c.erase(i); // 通过把erase的返回值
} // 赋给i来保持i有效
else
++i;
}
stl学习记录