C++的3种swap使用方式

C++的swap是非常重要的函数,尤其是在含有指针的类成员时,能提高效率。因此,对3种可能的swap编写方式作出总结,供必要的时候参考。

Article25.h文件及CPP文件

#ifndef ARTICLE25_H_
#define ARTICLE25_H_
#include <vector>
#include <typeinfo>
#include <iostream>

namespace Article25{
class WidgetImpl {
public:
    explicit WidgetImpl(int i1, int i2, int i3, const std::vector<double> &v1) : a(i1), b(i2), c(i3), v(v1){}
    const int get_a() const{
        return a;
    }
    const int get_b() const{
        return b;
    }
    const int get_c() const{
        return c;
    }
    const std::vector<double>& get_v() const{
        return v;
    }
private:
    int a, b, c;
    std::vector<double> v;
};

class Widget{
//    friend void swap(Widget &lhs, Widget &rhs); //第1种使用友元函数调用(注意:当且仅当需要在友元函数中访问类内部成员时,才建议使用友元函数)
public:
    explicit Widget(int i1, int i2, int i3, const std::vector<double> &v1): pImpl(new WidgetImpl(i1, i2, i3, v1)),
        use_count(new int(1)){}
    Widget(const Widget& rhs): pImpl(new WidgetImpl(rhs.pImpl->get_a(), rhs.pImpl->get_b(), rhs.pImpl->get_c()
            , rhs.pImpl->get_v())),    use_count(new int(1)){}
    Widget(Widget&& rhs): pImpl(std::move(rhs.pImpl)), use_count(std::move(rhs.use_count)){}
    Widget& operator=(const Widget& rhs){
        if(this != &rhs){
            free();
            ++*rhs.use_count;
            pImpl = rhs.pImpl;
            use_count = rhs.use_count;
        }
        return *this;
    }
    Widget& operator=(Widget &&rhs){
        if(this != &rhs){
            free();
            pImpl = std::move(rhs.pImpl);
            use_count = std::move(rhs.use_count);
        }
        return *this;
    }
    ~Widget(){
        free();
    }

    void swap(Widget& rhs){
        using std::swap;
        swap(pImpl, rhs.pImpl);
        swap(use_count, rhs.use_count);
    }
private:
    WidgetImpl* pImpl;
    int *use_count;

    void free(){
        if(--*use_count == 0){
            delete pImpl;
            delete use_count;
        }
    }
};

//extern void swap(Widget &lhs, Widget &rhs); //第2种方式,在命名空间Article25中定义访问函数,由于受到作用域限制,必须在类中需要一个public的成员swap函数。

}

Article25.cpp文件

-----------------------------------------------

#include "Article25.h"

namespace Article25{

//void swap(Widget &lhs, Widget &rhs){
//    lhs.swap(rhs);
//}

}

#endif /* ARTICLE25_H_ */

-------------------------------------------------------------------------

main.cpp文件

#include <iostream>

#include "Article25.h"

//第3种方式,在std命名空间中定义一个swap的模版函数特例,供其它函数调用,调用的原则是C++特例化及参数匹配调用。

namespace std{
    template<>
    void swap<Article25::Widget>(Article25::Widget &a, Article25::Widget &b){
        a.swap(b);
    }
}

int main() {

    Article25::Widget wi1(1, 2, 3, std::vector<double>({1.0, 2.0, 3.0}));
    Article25::Widget wi2(4, 5, 6, std::vector<double>({4.0, 5.0, 6.0}));
    Article25::Widget wi3(7, 8, 9, std::vector<double>({7.0, 8.0, 9.0}));
    wi1 = std::move(wi3);
    using std::swap;
    swap(wi1, wi2);
    return 0;
}

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值