条款7 使用new的指针的容器时,记得销毁容器需要释放内存
使用new的指针的容器时,记得销毁容器需要释放内存
举个例子:
class Widget {...};
void doSomething()
{
vector<Widget*> v;
for (int i = 0; i < 10; ++i)
{
v.push_back(new Widget());//创建Widget加入到容器
}
//容器销毁 随之容器的内容也就是 指针全部销毁,但是指针指向的内容没有被释放。这就造成了内存泄漏
}
当然解决办法也很简单,就是写一个for循环一个一个delete即可。
但是可以想象要写很长的代码,所以我们可以使用std::for_each替代!
需要传入一个函数对象:
template<typename T>
//unary_function 是使用一个参数创建函数对象的基类。 C++11 C++17 弃用了
struct DeleteObject : public unary_function<const T*, void>
{
//注意这块使用需要显示书写类型
void operator()(const T* ptr) const {
delete ptr;
}
};
//修改后的doSomething可以写成
void doSomething()
{
vector<Widget*> v;
for (int i = 0; i < 10; ++i)
{
v.push_back(new Widget());
}
//缺点就是需要显示 写<Widget>
std::for_each(v.begin(), v.end(), DeleteObject<Widget>());
}
我们可以换一种方式,不显示声明也可以。
struct DeleteObject
{
template<typename T>
void operator()(const T* ptr) const {
delete ptr;
}
};
//使用如下
std::for_each(v.begin(), v.end(), DeleteObject());
以上就是书上的部分,但是我们还可以更简化一些,就是我们有没有必要为了释放内存,而定义一个结构体。
新的做法
可以使用C++11的匿名函数优化一下:
//C++11推荐做法
std::function<void(Widget*)> del([](Widget*ptr)->void { delete ptr; });
//使用如下
std::for_each(v.begin(), v.end(), del);
是不是感觉更简单了(^__^) 。