swap函数实现

swap函数用于置换两对象的值,标准库中如下实现:
              template   < typename   T >
          void   swap   ( T &   ta   ,   T   &   tb )
       {
                 T   temp   ( ta );
                 ta   =   tb   ;
                 tb   =   temp   ;
       }
正确调用此模板方法,只需实现class的拷贝构造函数和赋值构造函数即可。但此处若 是pimpl(pointer to implement)的实现方式,若单纯使用上述方式每次拷贝的都是整个对象,现实现只交换指针的swap。   
        class   WidgetImpl
       {
          public :
                 WidgetImpl ( int   aa =0,   int   bb   =0,   int   cc =0)
                     :   a ( aa   ),   b (   bb ),   c   ( cc )
              {

              }
                 WidgetImpl ( const   WidgetImpl &   rhs )
                     :   a ( rhs   . a ),   b ( rhs   . b ),   c ( rhs   . c )
              {

              }
                 WidgetImpl &   operator   =( const   WidgetImpl &   rhs   )
              {
                        a   =   rhs   . a ;
                        b   =   rhs   . b ;
                        c   =   rhs   . c ;

                        return   * this   ;
              }
         private :
                 int   a   ,   b ,   c ;
       };

         class   Widget   {
          public :       
                 Widget ( WidgetImpl   *   p   = 0) :   pImpl ( p   )
              {

              }
                 Widget ( const   Widget &   rhs ): pImpl   ( pImpl   =   new   WidgetImpl   ()) // 牢记,否则为空指针
              {
                     *   pImpl   = * rhs   . pImpl ;   //   复制所指的对象 , 深拷贝
              }
                 Widget &   operator   =( const   Widget &   rhs   )
              {      
                        // 此处应该避免自我复制
                        pImpl   =   new   WidgetImpl ();
                     *   pImpl   = * rhs   . pImpl ;   //   复制所指的对象

                        return   * this   ;
              }
                 std :: ostream   &   print (   std :: ostream   & =   std ::   cout )   const   ;
              ~   Widget ()
              {
                        if ( pImpl   !=   NULL )
                              delete   pImpl   ;
              }

                 //member swap
                 void   swap   ( Widget &   other )
              {
                        using   std   :: swap ;
                        std :: cout   << pImpl <<   "   "   << other .   pImpl << std   :: endl ;
                        swap ( pImpl   ,   other .   pImpl );
              }
          private :
                 WidgetImpl *   pImpl   ;
       };
现有一种方式,即std::swap 的一个特化版本,实现如下:
namespace   std   {
          using   namespace   WidgetStuff ;
          template   <>
          void   swap   < Widget >(   Widget &   a   ,   Widget &   b )
       {
                swap(a.pImpl, b.pImpl);
       }
}
此实现不可编译,swap中访问了Widget的私有成员。我们令Widget声明一个名为swap的public成员函数做真正的置换工作,然后将std::swap特化,令它调用该成员函数:
// 函数模板特化
namespace   std   {
          using   namespace   WidgetStuff ;
          template   <>
          void   swap   < Widget >(   Widget &   a   ,   Widget &   b )
       {
                 a . swap   ( b );
       }
}
此种做法可行,但若Widget和WidgetImpl都是template class而非template,我们想这样写:
namespace  std  {
         using   namespace  WidgetStuff ;
         template  <typename T>
         void   swap  <  Widget<T> >(  Widget<T>   a  Widget<T> b  )
       {
                a  . swap  (  b );
       }
}
此处不可编译,因为函数模板不支持部分特化。
还可如下写:
namespace  std  {
         using   namespace  WidgetStuff ;
         template  <typename T>
         void   swap  (  Widget<T>   a  Widget<T> b  )
       {
                a  . swap  (  b );
       }
}
此处作为swap的一个重载版本,但std中不允许添加函数。此方法亦不可行。
我们的做法是定义一个non-member swap让他调用member swap.在我们的命名空间WidgetStuff中这样写:
              template  <typename T>
         void   swap  (  Widget<T>   a  Widget<T> b  )
       {
                a  . swap  (  b );
       }
具体实现代码见附件。

令swap可以用在赋值构造函数中防止自我复制。
class Widget {
     ...
     void swap(Widget& rhs);
     ...
};
Widget& Widget::operator=(const Widget& rhs)
{
     Widget tmp(rhs);
     swap(tmp);
     return *this;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值