交换操作
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、还有一个就是今天我搞了两节嘿嘿,所以会有两篇!!!
第二篇花了不少时间呢,不认真看,光扫几眼的话,我估计你们还不知道我在干嘛,嘿嘿!!
【足迹C++primer】44、交换操作
时间: 2024-10-13 12:26:48