﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-beautykingdom-随笔分类-GP_STL</title><link>http://www.cppblog.com/beautykingdom/category/7544.html</link><description /><language>zh-cn</language><lastBuildDate>Tue, 22 May 2012 06:26:51 GMT</lastBuildDate><pubDate>Tue, 22 May 2012 06:26:51 GMT</pubDate><ttl>60</ttl><item><title>boost 库 enable_shared_from_this 实现原理分析&lt;转&gt;</title><link>http://www.cppblog.com/beautykingdom/archive/2012/05/20/175469.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Sun, 20 May 2012 07:37:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2012/05/20/175469.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/175469.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2012/05/20/175469.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/175469.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/175469.html</trackback:ping><description><![CDATA[<div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">使用情景：当类对象被 shared_ptr 管理时，需要在类自己定义的函数里把当前类对象作为参数传给其他函数时，这时需要传递一个 shared_ptr ，否则就不能保持 shared_ptr 管理这个类对象的语义（因为有一个 raw pointer 指向这个类对象，而 shared_ptr 对类对象的这个引用没有计数，很有可能 shared_ptr 已经把类对象资源释放了，而那个调用函数还在使用类对象&#8212;&#8212;显然，这肯定会产生错误）。</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">很好奇这个模板类的实现。</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">先看看怎么使用：</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">对一个类 A ，当我们希望使用 shared_ptr 来管理其类对象时，而且需要在自己定义的函数里把类对象 shared_ptr （为什么不用普通指针，当我们使用智能指针管理资源时，必须统一使用智能指针，而不能在某些地方使用智能指针某些地方使用 raw pointer ，否则不能保持智能指针的语义，从而产生各种错误）传给其他函数时，可以让类 A 从 enable_shared_from_this 继承：</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">class A : public boost::enable_shared_from_this&lt;A&gt; {</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">};</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">然后在类 A 中需要传递类对象本身 shared_ptr 的地方使用 shared_from_this 函数来获得指向自身的 shared_ptr 。</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">一个非常有代表性的例子：</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "><a target="_blank" href="http://www.boost.org/doc/libs/1_39_0/doc/html/boost_asio/tutorial/tutdaytime3/src.html" style="color: #002280; text-decoration: none; ">http://www.boost.org/doc/libs/1_39_0/doc/html/boost_asio/tutorial/tutdaytime3/src.html</a></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">另《Beyond the C++ Standard Library》 shared_ptr 节也有很简单明了的例子。</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">实现原理：</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">首先要考虑的是：在类对象本身当中不能存储类对象本身的 shared_ptr ，否则类对象 shared_ptr 永远也不会为0了，从而这些资源永远不会释放，除非程序结束。</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">其次：类对象肯定是外部函数通过某种机制分配的，而且一经分配立即交给 shared_ptr 管理（再次强调一遍：给 shared_ptr 管理的资源必须在分配时交给 shared_ptr&nbsp;），而且以后凡是需要共享使用类对象的地方必须使用这个 shared_ptr 当作右值来构造产生或者拷贝产生另一个 shared_ptr 从而达到共享使用的目的。</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">有了以上两点的限制，要实现我们的目标（即在类对象内部使用类对象的 shared_ptr&nbsp;）有以下两种方案：</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">1、类对象的外部 shared_ptr 作为函数参数传给类的需要引用类对象自身的函数&#8212;&#8212;显然，这种方法很丑陋，而且并不是所有的情况都可行（如在外部 shared_ptr 不可见的作用域中就不行）；</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">2、类对象自身存储某种信息，在需要自身 shared_ptr 时来产生一个临时的 shared_ptr 。</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">显然，第2种方法更优雅（对于用户来说），关键是信息怎么存储？</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">对了， weak_ptr ！</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">实际上， boost 中就是这样实现的。</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">但现在的问题是：何时初始化这个 weak_ptr ？因为类对象生成时还没有生成相应的用来管理这个对象的 shared_ptr 。</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">boost 1.39.0 中是这样实现的：</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">首先生成类 A ：会依次调用 enable_shared_from_this 的构造函数（定义为 protected ），以及类 A 的构造函数。在调用 enable_shared_from_this 的构造函数时，会初始化定义在 enable_shared_from_this 中的 weak_ptr （调用其默认构造函数），这时这个 weak_ptr 是无效的（或者说不指向任何对象）。</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">接着：外部程序会把指向类 A 对象的指针作为初始化参数来初始化一个 shared_ptr 。</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">现在来看看 shared_ptr 是如何初始化的， shared_ptr 定义了如下构造函数：</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">template&lt;class Y&gt;</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">&nbsp;<wbr>&nbsp;<wbr>&nbsp;&nbsp;<wbr>explicit shared_ptr( Y * p ): px( p ), pn( p )&nbsp;<wbr></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">&nbsp;<wbr>&nbsp;<wbr>&nbsp;&nbsp;<wbr>{</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">&nbsp;<wbr>&nbsp;<wbr>&nbsp;&nbsp;<wbr>&nbsp;&nbsp;<wbr>&nbsp;&nbsp;<wbr>boost::detail::sp_enable_shared_from_this( this, p, p );</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">&nbsp;<wbr>&nbsp;<wbr>&nbsp;&nbsp;<wbr>}</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">里面调用了 &nbsp;<wbr>boost::detail::sp_enable_shared_from_this ：</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">template&lt; class X, class Y, class T &gt;</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">&nbsp;<wbr>inline void sp_enable_shared_from_this( boost::shared_ptr&lt;X&gt; const * ppx,</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">&nbsp;<wbr>Y const * py, boost::enable_shared_from_this&lt; T &gt; const * pe )</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">{</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">&nbsp;<wbr>&nbsp;<wbr>&nbsp;&nbsp;<wbr>if( pe != 0 )</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">&nbsp;<wbr>&nbsp;<wbr>&nbsp;&nbsp;<wbr>{</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">&nbsp;<wbr>&nbsp;<wbr>&nbsp;&nbsp;<wbr>&nbsp;&nbsp;<wbr>&nbsp;&nbsp;<wbr>pe-&gt;_internal_accept_owner( ppx, const_cast&lt; Y* &gt;( py ) );</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">&nbsp;<wbr>&nbsp;<wbr>&nbsp;&nbsp;<wbr>}</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">}</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">里面又调用了 enable_shared_from_this 的 _internal_accept_owner ：</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">template&lt;class X, class Y&gt; void _internal_accept_owner( shared_ptr&lt;X&gt; const * ppx, Y * py ) const</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">&nbsp;<wbr>&nbsp;<wbr>&nbsp;&nbsp;<wbr>{</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">&nbsp;<wbr>&nbsp;<wbr>&nbsp;&nbsp;<wbr>&nbsp;&nbsp;<wbr>&nbsp;&nbsp;<wbr>if( weak_this_.expired() )</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">&nbsp;<wbr>&nbsp;<wbr>&nbsp;&nbsp;<wbr>&nbsp;&nbsp;<wbr>&nbsp;&nbsp;<wbr>{</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">&nbsp;<wbr>&nbsp;<wbr>&nbsp;&nbsp;<wbr>&nbsp;&nbsp;<wbr>&nbsp;&nbsp;<wbr>&nbsp;&nbsp;<wbr>&nbsp;&nbsp;<wbr>weak_this_ = shared_ptr&lt;T&gt;( *ppx, py );</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">&nbsp;<wbr>&nbsp;<wbr>&nbsp;&nbsp;<wbr>&nbsp;&nbsp;<wbr>&nbsp;&nbsp;<wbr>}</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">&nbsp;<wbr>&nbsp;<wbr>&nbsp;&nbsp;<wbr>}</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">而在这里对 enable_shared_from_this 的成员 weak_ptr 进行拷贝赋值，使得整个 weak_ptr 作为类对象 &nbsp;<wbr>shared_ptr 的一个观察者。</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">这时，当类对象本身需要自身的 shared_ptr 时，就可以从这个 weak_ptr 来生成一个了。</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">原来如此。<br /><br /><br />from:<br /><a href="http://hi.baidu.com/jrckkyy/blog/item/0ef30b12778cdac5c2fd783b.html">http://blog.sina.com.cn/s/blog_62cd38470100g3dd.html</a><br /><br /><a href="http://hi.baidu.com/jrckkyy/blog/item/0ef30b12778cdac5c2fd783b.html">http://hi.baidu.com/jrckkyy/blog/item/0ef30b12778cdac5c2fd783b.html</a>&nbsp;<br /><br /><br /><br /><br /><br /><br /><br /></div><img src ="http://www.cppblog.com/beautykingdom/aggbug/175469.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2012-05-20 15:37 <a href="http://www.cppblog.com/beautykingdom/archive/2012/05/20/175469.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> STL通用工具</title><link>http://www.cppblog.com/beautykingdom/archive/2008/09/26/62789.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Fri, 26 Sep 2008 00:43:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2008/09/26/62789.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/62789.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2008/09/26/62789.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/62789.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/62789.html</trackback:ping><description><![CDATA[1.Pairs(对组) 常用的一个便捷函数<br>namespace std{<br>template &lt;typename T1,typename T2&gt;<br>pair&lt;T1,T2&gt; make_pair(const T1&amp; x,const T2&amp; y)<br>{<br>return pair&lt;T1,T2&gt;(x,y);<br>}<br>如：<br>std::pair&lt;int,char&gt;(42,&#8217;@&#8217;);<br>std::make_pair(42,&#8217;@&#8217;);<br><br>2.
<img src ="http://www.cppblog.com/beautykingdom/aggbug/62789.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2008-09-26 08:43 <a href="http://www.cppblog.com/beautykingdom/archive/2008/09/26/62789.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>STL容器 erase的使用陷井&lt;转载&gt;</title><link>http://www.cppblog.com/beautykingdom/archive/2008/07/09/55760.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Wed, 09 Jul 2008 14:32:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2008/07/09/55760.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/55760.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2008/07/09/55760.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/55760.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/55760.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp; 在STL（标准模板库）中经常会碰到要删除容器中部分元素的情况，本人在编程中就经常编写这方面的代码，在编码和测试过程中发现在STL中删除容器有很多陷阱，网上也有不少网友提到如何在STL中安全删除元素这些问题。本文将讨论编程过程中最经常使用的两个序列式容器vector、list中安全删除元素的方法和应该注意的问题，&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 其它如queue、stack等配接器容器（container adapter），由于它们有专属的操作行为，没有迭代器（iterator），不能采用本文介绍的删除方法，至于deque，它与vector的删除方法一样。STL容器功能强大，but no siliver bullet，如果你使用不当，也将让你吃尽苦头。<br>&nbsp;&nbsp;&nbsp; 这里最重要的是要理解erase成员函数，它删除了itVect迭代器指向的元素，并且返回要被删除的itVect之后的迭代器，迭代器相当于一个智能指
针，指向容器中的元素，现在删除了这个元素，将导致内存重新分配，相应指向这个元素的迭代器之后的迭代器就失效了，但erase成员函数返回要被删除的
itVect之后的迭代器。 <br></p>
<p>1．手工编写for循环代码删除STL序列式容器中元素的方法<br>例如，你能看出以下代码有什么问题？<br>例1：<br>#include &lt;iostream&gt;<br>#include &lt;vector&gt;<br>using namespace std;<br>void main( ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vector&lt;int&gt; vectInt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp; 初始化vector容器<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i = 0; i &lt; 5; i++ ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vectInt.push_back( i );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp; 以下代码是要删除所有值为4的元素<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vector&lt;int&gt;::iterator itVect = vectInt.begin();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ( ; itVect != vectInt.end();&nbsp;&nbsp; ++itVect ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( *itVect == 4 ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vectInt.erase( itVect );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int iSize = vectInt.size();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (&nbsp;&nbsp; i = 0 ; i &lt; iSize; i++ )&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt; " i= " &lt;&lt; i &lt;&lt;&nbsp;&nbsp; ", " &lt;&lt; vectInt[ i ] &lt;&lt; endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>} </p>
<p>&nbsp;&nbsp;&nbsp; 例1将导致程序未定义的错误，在windows中即是访问非法内存，程序当掉。因为vectInt.erase( itVect
);调用后itVect之后的迭代器已无效了，所以当执行++itVect后，*itVect访问了非法内存。例1也是初学者最容易犯的错误，这个错误也
比较容易发现。<br>
<br>例2：<br>#include &lt;iostream&gt;<br>#include &lt;vector&gt;<br>using namespace std;<br>void main( ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vector&lt;int&gt; vectInt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp; 初始化vector容器<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ( i = 0; i &lt; 5; i++ ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vectInt.push_back( i );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( 3 == i ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 使3的元素有两个，并且相临。这非常关键，否则将发现不了bug。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp; 具体解释见下。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vectInt.push_back( i );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vector&lt;int&gt;::iterator itVect = vectInt.begin();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vector&lt;int&gt;::iterator itVectEnd = vectInt.end(); //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 防止for多重计算<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp; 以下代码是要删除所有值为3的元素<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ( ; itVect != itVectEnd; ++itVect ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( *itVect == 3 ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; itVect = vectInt.erase( itVect );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int iSize = vectInt.size();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (&nbsp;&nbsp; i = 0 ; i &lt; iSize; i++ )&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt; " i= " &lt;&lt; i &lt;&lt;&nbsp;&nbsp; ", " &lt;&lt; vectInt[ i ] &lt;&lt; endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>例2可能会导致不能把vectInt中所有为3的元素删除掉。因为第一次删除成功时，itVect = vectInt.erase( itVect
);itVect为指向3之后的位置，之后再执行++itVect，itVect就掉过了被删除元素3之后的元素3，导致只删除了一个为3的元素，这个
bug比较隐蔽，因为如果不是两个均为3的元素相临，就将很难捕捉到这个bug，程序有可能在一段时间运行良好，但如碰到容器中两值相同的元素相临，则程
序就要出问题。
<br></p>
<p><br>例3：<br>#include &lt;iostream&gt;<br>#include &lt;vector&gt;<br>using namespace std;<br>void main( ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vector&lt;int&gt; vectInt( 5 );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vectInt[ 0 ] = 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vectInt[ 1 ] = 1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vectInt[ 2 ] = 2;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vectInt[ 3 ] = 3;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vectInt[ 4 ] = 4; //&nbsp;&nbsp;&nbsp;&nbsp; 替换为 vectInt[ 4 ] = 3;试试<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vector&lt;int&gt;::iterator itVect = vectInt.begin();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vector&lt;int&gt;::iterator itVectEnd = vectInt.end(); //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 防止for多重计算<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp; 以下代码是要删除所有值为3的元素<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ( ; itVect != itVectEnd; ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( *itVect == 3 ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; itVect = vectInt.erase( itVect );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ++itVect;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int iSize = vectInt.size();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (&nbsp;&nbsp; i = 0 ; i &lt; iSize; i++ )&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt; " i= " &lt;&lt; i &lt;&lt;&nbsp;&nbsp; ", " &lt;&lt; vectInt[ i ] &lt;&lt; endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>}<br>例3，对于本例你可能要说程序没有任何问题，解决了上面的两个bug，程序也运行正常。但且慢，你把 &#8220;vectInt[ 4 ] = 4;&#8221; 这一行改为 &#8220;vectInt[ 4 ] = 3;&#8221;试试，一运行，程序当掉，访问非法内存！你疑惑不解：从程序看不出bug，而且我还把vectInt.end()放在外面计算以防止for多重计算，提高效率。哈哈，问题就出在最后一句话！算法大师Donald Knuth有一句名言：不成熟的优化是一切恶果的根源（ Permature optimization is the root of all evil ）。由于在for循环中要删除元素，则vectInt.end()是会变化的，所以不能在for循环外计算，而是每删除一次都要重新计算，所以应放在 for循环内。那你要问，为什么把 &#8220;vectInt[ 4 ] = 4;&#8221; 这一行改为 &#8220;vectInt[ 4 ] = 3;&#8221;程序就会当掉，而不改程序就很正常呢？这就跟vector的实现机制有关了。下面以图例详细解释。<br>vectInt的初始状态为：<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | end<br>0&nbsp;&nbsp; 1&nbsp;&nbsp; 2&nbsp;&nbsp; 3&nbsp;&nbsp; 4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><br>删除3后，<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |新的end&nbsp;&nbsp; | 原来的end<br>0&nbsp;&nbsp; 1&nbsp;&nbsp; 2 &nbsp; 4&nbsp;&nbsp; 4&nbsp;&nbsp;&nbsp;&nbsp; <br><br><br>注意上面&#8220;新的end&#8221;指向的内存并没有被清除，为了效率，vector会申请超过需要的内存保存数据，删除数据时也不会把多余的内存删除。<br><br>然后itVect再执行++itVect，因为此时*itVect等于4，所以继续循环， 这时itVect 等于&#8220;新的end&#8221;但不等于&#8220;原来的end&#8221;（它即为itVectEnd），所以继续，因为 *itVect访问的是只读内存得到的值为4，不等于3，故不删除，然后执行++itVect此时itVect等于itVectEnd退出循环。从上面过程可以看出，程序多循环了一次（删除几次，就要多循环几次），但程序正常运行。<br><br>如果把 &#8220;vectInt[ 4 ] = 4;&#8221; 这一行改为 &#8220;vectInt[ 4 ] = 3;&#8221;过程如下：<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | end<br>0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3&nbsp;&nbsp;&nbsp;&nbsp; </p>
<p>&nbsp;&nbsp;<br>删除3后，<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |新的end&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |原来的 end<br>0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><br>删除第2个3后，<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |新的end&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |原来的 end<br>0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><br>这时itVect 等于&#8220;新的end&#8221;但不等于&#8220;原来的end&#8221;（它即为itVectEnd），所以继续，因为 *itVect访问的是只读内存得到的值为3，等于3，所以执行删除，但因为*itVect访问的是只读内存不能删除，所以程序当掉。<br><br>综上，我们知道当要删除的值在容器末尾时，会导致程序删除非法内存，程序当掉；即使程序正常运行，也是for循环多执行了等于删除个数的循环。所以把 vectInt.end()放在for循环外面执行，完全是错误的。对于list容器，list.end()在删除过程中是不会变的，可以把它放在for 循环外面计算，但由于list.end()是个常量，把list.end()放在for循环中计算编译器应该可以优化它。从安全考虑，除非你能保证for 循环中不会改变容器的大小，否则都应该对容器的值在for循环中计算，对于 vectInt.size()这样的计算，也应该在for循环中计算，不要因为微小的优化而导致程序出错。<br><br><br>正确的方法：<br>例4：<br>#include &lt;iostream&gt;<br>#include &lt;vector&gt;<br>using namespace std;<br>void main( ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vector&lt;int&gt; vectInt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (&nbsp;&nbsp; i = 0; i &lt; 5; i++ ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vectInt.push_back( i );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( 3 == i ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 使3的元素有两个，并且相临。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vectInt.push_back( i );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vector&lt;int&gt;::iterator itVect = vectInt.begin();<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp; 以下代码是要删除所有值为3的元素<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ( ; itVect != vectInt.end();&nbsp;&nbsp; ) {&nbsp;&nbsp; // 删除 ++itVect{<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( *itVect == 3 ) {<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; itVect = vectInt.erase( itVect );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else { <br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ++itVect;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp; 把vectInt.size()放在for循环中<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (&nbsp;&nbsp; i = 0 ; i &lt; vectInt.size(); i++ )&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt; " i= " &lt;&lt; i &lt;&lt;&nbsp;&nbsp; ", " &lt;&lt; vectInt[ i ] &lt;&lt; endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br><br>运行结果为：<br>i= 0, 0<br>i= 1, 1<br>i= 2, 2<br>i= 3, 4<br><br>从结果显示值为3的元素确实被删除了。<br><br>2.使用STL中通用算法或容器成员函数删除元素的方法<br>以上手工编写for循环代码删除容器中元素的方法也有一些问题，如果判断条件特别复杂，又有循环判断的话，循环中间又有异常处理的话，++itVect的位置就要小心放置了，稍不留意就要出错。所以手工编写代码删除容器中元素的方法不太安全，代码重复，也不够优雅，要注意的地方很多。<br><br>对于这种情况，可以考虑使用STL中通用算法remvoe()和remove_if()帮忙。而remvoe()和remove_if()这两个算法也有一个问题需要程序员特别小心。在通用算法中的 remove（包括remove_if）函数，并不真正从容器中删除元素，而是&#8220;应被删除的元素&#8221;被其后的&#8220;未被删除的元素&#8221;覆盖。返回值ForwardIterator指向经移除后的最后元素的下一位置。如vector{0,1,2,3,3,4}，执行remove()，希望移除所有值为3的元素，结果为{0,1,2,4,3,4}，返回值 ForwardIterator指向第5个元素。即：<br><br>0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4&nbsp;&nbsp; 移除前<br><br>0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4&nbsp;&nbsp; 移除后<br><br><br>移除值为3的元素。移除后3被其后的4替代，最后两位元素为残余数据。<br><br>例 5：<br><br>void main() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vector&lt;int&gt; vectInt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i = 0; i &lt; 5; i++ ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vectInt.push_back( i );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( 3 == i ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vectInt.push_back( i );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; remove( vectInt.begin(), vectInt.end(), 3 );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt; " after deleted , size = " &lt;&lt; vectInt.size() &lt;&lt; endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ( i = 0; i &lt; vectInt.size();; i++ ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt; "i = " &lt;&lt; i &lt;&lt; " , " &lt;&lt; vectInt[i] &lt;&lt; endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>}<br>运行结果为：<br>after deleted , size = 6 // 从这行可以看出，移除后容器的大小没变<br>i = 0 , 0<br>i = 1 , 1<br>i = 2 , 2<br>i = 3 , 4 //&nbsp;&nbsp; 从这行可以看出：&#8220;应被删除的元素&#8221;3 被其后的&#8220;未被删除的元素&#8221;4覆盖<br>i = 4 , 3<br>i = 5 , 4&nbsp;&nbsp;&nbsp;&nbsp; <br><br>所以要彻底删除还应该把后面的残余数据删除掉，这可以通过调用容器的成员函数erase()做到。<br><br>例 6：<br>void main() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vector&lt;int&gt; vectInt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i = 0; i &lt; 5; i++ ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vectInt.push_back( i );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( 3 == i ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vectInt.push_back( i );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vectInt.erase( remove( vectInt.begin(), vectInt.end(), 3 ), vectInt.end() );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt; " after deleted , size = " &lt;&lt; vectInt.size() &lt;&lt; endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ( i = 0; i &lt; vectInt.size();; i++ ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt; "i = " &lt;&lt; i &lt;&lt; " , " &lt;&lt; vectInt[i] &lt;&lt; endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>}<br><br>运行结果为：<br>after deleted , size = 4 // 从这行可以看出，删除后容器的大小变化了<br>i = 0 , 0<br>i = 1 , 1<br>i = 2 , 2<br>i = 3 , 4<br>从结果可以看出，所有值为3的元素确实被删除了。<br>对于vector容器存放其他比较复杂的对象，就可以用remove_if()加函数对象（Function Object）的方法。<br>如：<br>例7：<br>#include &lt;iostream&gt;<br>#include &lt;sstream&gt;<br>#include &lt;string&gt;<br>#include &lt;vector&gt;<br>#include &lt;algorithm&gt;<br>#include &lt;list&gt;<br>using namespace std;<br>class CTest {<br>public:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CTest( const string&amp; str, int iPrice ) : m_strName( str ), m_iPrice( iPrice ) { }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void vPrint() { cout &lt;&lt; "name=" &lt;&lt; m_strName &lt;&lt; " price = " &lt;&lt; m_iPrice &lt;&lt; endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>private:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string m_strName;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp; m_iPrice;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp; 由于两个函数对象要访问CTest类的private成员，所以设为友员。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; friend class CStrFunc;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; friend class CIntFunc;<br>};<br><br>//&nbsp;&nbsp;&nbsp;&nbsp; 函数对象，根据string比较<br>class CStrFunc {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string m_str;<br>public:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CStrFunc( const string&amp; str ) : m_str( str ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bool operator() ( const CTest&amp; left ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ( m_str == left.m_strName ) ? true : false;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>};<br><br>//&nbsp;&nbsp;&nbsp;&nbsp; 函数对象，根据int比较<br>class CIntFunc {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int m_iPrice;<br>public:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CIntFunc( int iPrice ) : m_iPrice( iPrice ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bool operator() ( const CTest&amp; left ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ( m_iPrice == left.m_iPrice ) ? true : false;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>};<br><br>void main( ) {<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vector&lt; CTest &gt; vectTest;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (&nbsp;&nbsp; i = 0; i &lt; 5 ; i++ ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stringstream stream; //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 流格式化符，把int转化为string<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stream &lt;&lt; i;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string str = stream.str();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CTest clTest( str, i );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vectTest.push_back( clTest );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (&nbsp;&nbsp; i = 0 ; i &lt; vectTest.size(); i++ )&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vectTest[ i ].vPrint();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp; 删除所有m_strName = "3"的元素<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vectTest.erase( remove_if( vectTest.begin(), vectTest.end(), CStrFunc( "3" ) ),<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vectTest.end() );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt; "delete 3 after : " &lt;&lt; endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (&nbsp;&nbsp; i = 0 ; i &lt; vectTest.size(); i++ )&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vectTest[ i ].vPrint();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp; 删除所有m_iPrice = 2的元素<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vectTest.erase( remove_if( vectTest.begin(), vectTest.end(), CIntFunc( 2 ) ),<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vectTest.end() );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt; "delete 2 after : " &lt;&lt; endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (&nbsp;&nbsp; i = 0 ; i &lt; vectTest.size(); i++ )&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vectTest[ i ].vPrint();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>}<br>手工编写for循环代码删除STL序列式容器中元素的方法，使用STL中通用算法或容器成员函数删除元素的方法，两者之间的比较：<br>1．&nbsp;&nbsp; 前者代码重复。<br>2．&nbsp;&nbsp; 前者容易出错，不够清晰。<br>3．&nbsp;&nbsp; 效率：<br>0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7<br>0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7<br>0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7<br>用第一种方法删除所有值为2的元素<br>从上图可以看出，每删除一个元素，后面的所有元素都到往前移动一位，导致一次内存大搬迁。<br><br>0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7<br>0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7<br>0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7<br><br>用第二种方法删除所有值为2的元素<br>从上面可以看出，删除时元素2被后面元素覆盖，不会到元素移位和内存大搬迁，残余数据留到末尾一次全部删除，也不会导致内存大搬迁，所以后者的方法要比前者在效率上好很多。&nbsp;<br><br>3．list容器中删除元素的方法<br>对于list容器，由于list本身有remove和remove_if的成员函数，所以最好优先考虑list自己的算法，对于remove函数，比较简单，不再讨论，对于remove_if函数，本人发现在vc6.0中有重大问题。我试了多种函数对象，总是编译不过，通过查看源代码，才发现VC6.0中对remove_if()函数作了简化，只提供了一种比较函数，它只能删除不等于某值的元素，VC6.0种remove_if()函数的源码如下：<br>typedef binder2nd&lt;not_equal_to&lt;_Ty&gt; &gt; _Pr1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void remove_if(_Pr1 _Pr)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {iterator _L = end();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (iterator _F = begin(); _F != _L; )<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (_Pr(*_F))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; erase(_F++);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ++_F; }<br>从源码中可以看出，remove_if中_Pr1函数对象被固定为binder2nd&lt;not_equal_to&lt;_Ty&gt; &gt;一种格式。而在VC7.0中已经修改了这个bug，源码如下：<br>template&lt;class _Pr1&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void remove_if(_Pr1 _Pred)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp; // erase each element satisfying _Pr1<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; iterator _Last = end();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (iterator _First = begin(); _First != _Last; )<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (_Pred(*_First))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; erase(_First++);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ++_First;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>在VC7.0中remove_if()是成员模板函数，可以用任何判断条件的函数对象。<br>例如：<br>例 8：<br>#include &lt;iostream&gt;<br>#include &lt;string&gt;<br>#include &lt;list&gt;<br>#include &lt;algorithm&gt;<br>using namespace std;<br>class CTest{<br>public:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CTest( int i ) : m_iPrice ( i ) {&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int operator == ( const CTest&amp; right ) const{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ( m_iPrice == right.m_iPrice ) ? 1 : 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int operator != ( const CTest&amp; right ) const{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ( m_iPrice != right.m_iPrice ) ? 1 : 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int operator &lt; ( const CTest&amp; right ) const {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ( m_iPrice &lt; right.m_iPrice ) ? 1 : 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>private:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int m_iPrice;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; friend class CTestFunc;<br>};<br>class CTestFunc {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 函数对象<br>public:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int m_value;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CTestFunc( int i ) : m_value( i ) {}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bool operator () ( const CTest&amp; clFirst ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ( clFirst.m_iPrice == m_value ) ? true : false;&nbsp;&nbsp;&nbsp;&nbsp; }<br>};<br>void main() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; list&lt; CTest &gt; listTest;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ( int i = 0; i &lt; 5; i++ ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CTest clTest( i );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; listTest.push_back( clTest );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt; "remove before : " &lt;&lt; listTest.size() &lt;&lt; endl;<br>//&nbsp;&nbsp;&nbsp;&nbsp; 删除所有为2的元素<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; listTest.remove_if( CTestFunc( 2 )&nbsp;&nbsp; ); //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这条语句在vc6.0中不能编译通过,VC7.0中可以<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt; "remove after : 2, size =&nbsp;&nbsp; " &lt;&lt; listTest.size() &lt;&lt; endl;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp; 删除所以不等于2的元素，VC6.0中只能以这种方式调用remove_if()函数<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; listTest.remove_if(&nbsp;&nbsp; bind2nd( not_equal_to&lt;CTest&gt;(), 2 )&nbsp;&nbsp;&nbsp;&nbsp; );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt; "remove after not equal to 2, size =&nbsp;&nbsp; " &lt;&lt; listTest.size() &lt;&lt; endl;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp; 因为CTest类提供了==、&lt; 成员函数，所以也可以用remove函数<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; listTest.remove( 2 ); //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 删除所有为2的元素<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt; "remove after : 2, size =&nbsp;&nbsp; " &lt;&lt; listTest.size() &lt;&lt; endl;<br>}<br><br>不知道在VC6.0中能否突破只能函数对象被固定为binder2nd&lt;not_equal_to&lt;_Ty&gt; &gt;一种格式的限制？欢迎诸位大虾不吝赐教。不过采用通用算法remove_if只是多了几次对象的赋值的负担，如果对象不是太大，用通用算法的性能也是可以接受的。<br><br>另外，这些天使用了VC7.0后，感觉非常棒，不仅几乎符合Standard C++规范，错误提示也更清晰，而编译速度和编译后的文件大小大大减小，如我原来的一个大量使用了模板的程序，用VC6.0编译后Release版的可执行文件大小为1.2M，用VC7.0编译后只有420K，我想可能VC7.0在代码优化和模板代码的膨胀等方面有了极大的改善；在STL的实现上也有了极大的改进，把原来的一些效率不好的地方都改进了，处理策略基本与SGI STL一致。<br><br>4．STL容器中元素为指针情况下的删除方法<br>对于容器中的元素为指针的删除方法。如果容器中的元素为指针则不能用上面介绍的用通过算法或成员函数的方法删除元素，因为那样做会导致内存泄露，容器中的元素为指针指向的内存没有释放，在这种情况下有以下方法解决：<br><br>1．&nbsp;&nbsp; 尽可能不用指针作为容器的元素。<br><br>2．&nbsp;&nbsp; 如果是因为要减少对象拷贝和赋值方面的负担，而要在容器中存放指针的话，可以考虑用boost库中的智能指针shared_ptr包装指针，达到容器中引用的语意。<br><br>3．&nbsp;&nbsp; 如果你不希望因为使用boost::shared_ptr增加引用计数的负担，认为引入智能指针不好理解，那么你用指针作为容器的元素要千万小心，这时你要自己管理内存。<br><br>例如：&nbsp;&nbsp;&nbsp;&nbsp;<br><br>例 9：用boost库中的智能指针shared_ptr包装指针的例子：<br>#include &lt;iostream&gt;<br>#include &lt;sstream&gt;<br>#include &lt;string&gt;<br>#include &lt;vector&gt;<br>#include &lt;algorithm&gt;<br>#include &lt;list&gt;<br>#include &lt;boost\smart_ptr.hpp&gt; // 要包含BOOST类库中智能指针的头文件<br>using namespace std;<br>class CTest {<br>public:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CTest( const string&amp; str, int iPrice ) : m_strName( str ), m_iPrice( iPrice ) { }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void vPrint() { cout &lt;&lt; "name=" &lt;&lt; m_strName &lt;&lt; " price = " &lt;&lt; m_iPrice &lt;&lt; endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br><br>private:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string m_strName;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp; m_iPrice;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; friend class CStrFunc;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; friend class CIntFunc;<br>};<br><br>//&nbsp;&nbsp;&nbsp;&nbsp; 函数对象，根据string比较<br>class CStrFunc {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string m_str;<br><br>public:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CStrFunc( const string&amp; str ) : m_str( str ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp; 此处要改为boost::shared_ptr&lt;CTest&gt;&amp;，因为vector容器中的元素为<br>//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boost::shared_ptr&lt;CTest&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bool operator() ( const boost::shared_ptr&lt;CTest&gt;&amp; left ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ( m_str == (*left).m_strName ) ? true : false;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br><br>};<br><br>//&nbsp;&nbsp;&nbsp;&nbsp; 函数对象，根据int比较<br>class CIntFunc {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int m_iPrice;<br>public:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CIntFunc( int iPrice ) : m_iPrice( iPrice ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>//&nbsp;&nbsp;&nbsp;&nbsp; 此处要改为boost::shared_ptr&lt;CTest&gt;&amp;，因为vector容器中的元素为<br>//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boost::shared_ptr&lt;CTest&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bool operator() ( const boost::shared_ptr&lt;CTest&gt;&amp; left ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ( m_iPrice == (*left).m_iPrice ) ? true : false;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>};<br>void main( ) {<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vector&lt; boost::shared_ptr&lt;CTest&gt;&nbsp;&nbsp; &gt; vectTest;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (&nbsp;&nbsp; i = 0; i &lt; 5 ; i++ ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stringstream stream;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stream &lt;&lt; i;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string str = stream.str();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boost::shared_ptr&lt;CTest&gt;&nbsp;&nbsp; ptrShare( new CTest( str, i ) );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vectTest.push_back( ptrShare );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (&nbsp;&nbsp; i = 0 ; i &lt; vectTest.size(); i++ )&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ( *vectTest[ i ] ).vPrint();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp; 删除所有m_strName = "3"的元素<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vectTest.erase( remove_if( vectTest.begin(), vectTest.end(), CStrFunc( "3" ) ),<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vectTest.end() );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt; "delete 3 after : " &lt;&lt; endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (&nbsp;&nbsp; i = 0 ; i &lt; vectTest.size(); i++ )&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ( *vectTest[ i ] ).vPrint();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp; 删除所有m_iPrice = 2的元素<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vectTest.erase( remove_if( vectTest.begin(), vectTest.end(), CIntFunc( 2 ) ),<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vectTest.end() );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt; "delete 2 after : " &lt;&lt; endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (&nbsp;&nbsp; i = 0 ; i &lt; vectTest.size(); i++ )&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ( *vectTest[ i ] ).vPrint();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>}<br><br>以上代码不会导致内存泄露。<br><br>例 10：自己编程删除容器中元素为指针的例子：<br><br>#include &lt;iostream&gt;<br>#include &lt;sstream&gt;<br>#include &lt;string&gt;<br>#include &lt;vector&gt;<br>#include &lt;algorithm&gt;<br>using namespace std;<br>class CTest {<br>public:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CTest( const string&amp; str, int iPrice ) : m_strName( str ), m_iPrice( iPrice ) { }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void vPrint() { cout &lt;&lt; "name=" &lt;&lt; m_strName &lt;&lt; " price = " &lt;&lt; m_iPrice &lt;&lt; endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>private:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string m_strName;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp; m_iPrice;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp; 声明友员函数，因为vDeleteVector函数要访问CTest的private成员变量<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; friend void vDeleteVector( vector&lt; CTest*&nbsp;&nbsp; &gt;&amp; vectTest, const string&amp; str );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; friend void vDeleteVector( vector&lt; CTest*&nbsp;&nbsp; &gt;&amp; vectTest, int iPrice );<br>};<br>//&nbsp;&nbsp;&nbsp;&nbsp; 根据CTest类中m_strName比较<br>void vDeleteVector( vector&lt; CTest*&nbsp;&nbsp; &gt;&amp; vectTest, const string&amp; str ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vector&lt; CTest* &gt;::iterator itVect = vectTest.begin();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ( ; itVect != vectTest.end();; ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( (*itVect)-&gt;m_strName == str ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 删除vector容器中指针元素指向的内容，防止内存泄露<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; delete *itVect;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; itVect = vectTest.erase( itVect );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ++itVect;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>}<br>//&nbsp;&nbsp;&nbsp;&nbsp; 根据CTest类中m_iPrice比较<br>void vDeleteVector( vector&lt; CTest*&nbsp;&nbsp; &gt;&amp; vectTest, int iPrice ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vector&lt; CTest* &gt;::iterator itVect = vectTest.begin();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ( ; itVect != vectTest.end(); ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( (*itVect)-&gt;m_iPrice == iPrice ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 删除vector容器中指针元素指向的内容，防止内存泄露<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; delete *itVect;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; itVect = vectTest.erase( itVect );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ++itVect;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>}<br><br>void main( ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vector&lt; CTest*&nbsp;&nbsp; &gt; vectTest;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (&nbsp;&nbsp; i = 0; i &lt; 5 ; i++ ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stringstream stream;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stream &lt;&lt; i;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string str = stream.str();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CTest* pclTest =&nbsp;&nbsp; new CTest( str, i ) ;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vectTest.push_back( pclTest );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (&nbsp;&nbsp; i = 0 ; i &lt; vectTest.size(); i++ )&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vectTest[ i ]-&gt;vPrint();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp; 删除所有m_strName = "5"的元素<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vDeleteVector( vectTest, "3" );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt; "delete 3 after : " &lt;&lt; endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (&nbsp;&nbsp; i = 0 ; i &lt; vectTest.size(); i++ )&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vectTest[ i ]-&gt;vPrint();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp; 删除所有m_iPrice = 2的元素<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vDeleteVector( vectTest, 2 );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt; "delete 2 after : " &lt;&lt; endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (&nbsp;&nbsp; i = 0 ; i &lt; vectTest.size(); i++ )&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vectTest[ i ]-&gt;vPrint();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>}<br>原则：<br>1．&nbsp;&nbsp; 尽可能用通用算法。相信STL的算法要比自己的实现高效、优雅、安全。<br>2．&nbsp;&nbsp; 优先用容器自身的成员函数。 见《Effective STL》中 Item 44: Prefer member functions to algorithms with the same names<br>3．&nbsp;&nbsp; 尽可能熟悉函数对象。<br>4．&nbsp;&nbsp; 多看STL的源码，了解其实作。<br>5．&nbsp;&nbsp; 不成熟的优化是一切恶果的根源。编写代码，安全第一。<br>综上，在STL中删除容器中部分元素时要特别小心，不过通过使用通用算法或容器本身的删除函数，能大大减小重复代码和程序出错的机会，能够使代码得到优化，生成高效的代码。 <br><br></p><img src ="http://www.cppblog.com/beautykingdom/aggbug/55760.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2008-07-09 22:32 <a href="http://www.cppblog.com/beautykingdom/archive/2008/07/09/55760.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>