交换操作
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
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、还有一个就是今天我搞了两节嘿嘿,所以会有两篇!!!
第二篇花了不少时间呢,不认真看,光扫几眼的话,我估计你们还不知道我在干嘛,嘿嘿!!