首页 > 代码库 > 【足迹C++primer】44、交换操作

【足迹C++primer】44、交换操作

交换操作

class   HasPtr
{
    friend void fun2();
    friend void swap(HasPtr&, HasPtr&);
public:
//    HasPtr()=default;
    HasPtr(const string &s=string()):ps(new string(s)), i(0){}
    //对ps指向的string,每个HasPtr对象都有自己的拷贝
    HasPtr(const HasPtr &p):ps(new string(*p.ps)), i(p.i) {}
    HasPtr & operator=(const HasPtr &);
    ~HasPtr() {delete ps;}

private:
    string *ps;
    int     i;
};

类值拷贝赋值运算符

HasPtr& HasPtr::operator=(const HasPtr &rhs)
{
    auto newp=new string(*rhs.ps);      //拷贝底层string
    delete ps;          //释放旧内存
    ps=newp;            //从右侧运算对象拷贝数据到本对象
    i=rhs.i;
    return *this;       //返回本对象
}

void fun1()
{
    HasPtr v1,v2;
    HasPtr temp=v1;     //创建v1的值的一个临时副本
    v1=v2;              //将v2的值赋予v1
    v2=temp;            //将保持的v1的值赋予
}


void fun2()
{
    HasPtr v1,v2;
    string *temp=v1.ps; //为v1.ps中的指针创建一个副本
    v1.ps=v2.ps;        //将v2.ps中的指针赋予v1.ps
    v2.ps=temp;         //将保存的v1.ps的原来的指针赋予v2.ps
}

编写我们自己的swap函数

inline void swap(HasPtr &lhs, HasPtr &rhs)
{
    using std::swap;
    swap(lhs.ps, rhs.ps);   //交换指针,而不是string数据
    swap(lhs.i, rhs.i);     //交换int成员
}

//swap的纯在就是为了优化代码

swap函数应该调用swap,而不是std::swap

class Foo
{
public:
    int h;
};

void swap(Foo &lhs, Foo &rhs)
{
    //错误:这个函数使用了标准库版本的swap,而不是HasPtr版本
    std::swap(lhs.h, rhs.h);
    //交换类型Foo的其他成员
}


编译会通过,且正常运行,但是这里我们显示使用了标准库里面的swap

在赋值运算符中使用swap

class   HasPtr2
{
    friend void fun2();
//    friend void swap(HasPtr2&, HasPtr2&);
public:
//    HasPtr()=default;
    HasPtr2(const string &s=string()):ps(new string(s)), i(0){}
    //对ps指向的string,每个HasPtr对象都有自己的拷贝
    HasPtr2(const HasPtr2 &p):ps(new string(*p.ps)), i(p.i) {}
    HasPtr2 & operator=(HasPtr2 );
    ~HasPtr2() {delete ps;}

private:
    string *ps;
    int     i;
};

定义swap的类通常用swap来定义他们的赋值运算符。
动用了一种拷贝并交技术
<pre name="code" class="cpp">//注意rhs是按值传递的,意味着HasPtr的拷贝构造函数
//将右侧运算对象中的string拷贝到rhs
HasPtr2& HasPtr2::operator=(HasPtr2 rhs)
{
    //交换左侧运算对象和局部变量rhs的内容
    swap(*this, rhs);       //rhs现在指向本对象曾经使用的内存
    return *this;           //rhs被销毁,从而delete了rhs中的指针
}


全代码!!

/**
* 功能:13.3交换操作
* 时间:2014年7月14日09:27:08
* 作者:cutter_point
*/

#include<iostream>
#include<string>

using namespace std;


class   HasPtr
{
    friend void fun2();
    friend void swap(HasPtr&, HasPtr&);
public:
//    HasPtr()=default;
    HasPtr(const string &s=string()):ps(new string(s)), i(0){}
    //对ps指向的string,每个HasPtr对象都有自己的拷贝
    HasPtr(const HasPtr &p):ps(new string(*p.ps)), i(p.i) {}
    HasPtr & operator=(const HasPtr &);
    ~HasPtr() {delete ps;}

private:
    string *ps;
    int     i;
};

/**
类值拷贝赋值运算符
*/
HasPtr& HasPtr::operator=(const HasPtr &rhs)
{
    auto newp=new string(*rhs.ps);      //拷贝底层string
    delete ps;          //释放旧内存
    ps=newp;            //从右侧运算对象拷贝数据到本对象
    i=rhs.i;
    return *this;       //返回本对象
}

void fun1()
{
    HasPtr v1,v2;
    HasPtr temp=v1;     //创建v1的值的一个临时副本
    v1=v2;              //将v2的值赋予v1
    v2=temp;            //将保持的v1的值赋予
}


void fun2()
{
    HasPtr v1,v2;
    string *temp=v1.ps; //为v1.ps中的指针创建一个副本
    v1.ps=v2.ps;        //将v2.ps中的指针赋予v1.ps
    v2.ps=temp;         //将保存的v1.ps的原来的指针赋予v2.ps
}

/**
编写我们自己的swap函数
*/
inline void swap(HasPtr &lhs, HasPtr &rhs)
{
    using std::swap;
    swap(lhs.ps, rhs.ps);   //交换指针,而不是string数据
    swap(lhs.i, rhs.i);     //交换int成员
}

//swap的纯在就是为了优化代码

/**
swap函数应该调用swap,而不是std::swap
*/

class Foo
{
public:
    int h;
};

void swap(Foo &lhs, Foo &rhs)
{
    //错误:这个函数使用了标准库版本的swap,而不是HasPtr版本
    std::swap(lhs.h, rhs.h);
    //交换类型Foo的其他成员
}
/*
编译会通过,且正常运行,但是这里我们显示使用了标准库里面的swap
*/

/**
在赋值运算符中使用swap
*/

class   HasPtr2
{
    friend void fun2();
//    friend void swap(HasPtr2&, HasPtr2&);
public:
//    HasPtr()=default;
    HasPtr2(const string &s=string()):ps(new string(s)), i(0){}
    //对ps指向的string,每个HasPtr对象都有自己的拷贝
    HasPtr2(const HasPtr2 &p):ps(new string(*p.ps)), i(p.i) {}
    HasPtr2 & operator=(HasPtr2 );
    ~HasPtr2() {delete ps;}

private:
    string *ps;
    int     i;
};

/*
定义swap的类通常用swap来定义他们的赋值运算符。
动用了一种拷贝并交技术
*/
//注意rhs是按值传递的,意味着HasPtr的拷贝构造函数
//将右侧运算对象中的string拷贝到rhs
HasPtr2& HasPtr2::operator=(HasPtr2 rhs)
{
    //交换左侧运算对象和局部变量rhs的内容
    swap(*this, rhs);       //rhs现在指向本对象曾经使用的内存
    return *this;           //rhs被销毁,从而delete了rhs中的指针
}

int main()
{
    return 0;
}

PS:i`m so sorry,今天上传的晚了很多,有两个原因:
1、今天不知道为什么这网和我闹矛盾了,老是断网,那是非常不稳定!!
2、还有一个就是今天我搞了两节嘿嘿,所以会有两篇!!!
第二篇花了不少时间呢,不认真看,光扫几眼的话,我估计你们还不知道我在干嘛,嘿嘿!!