练习13.29:
该swap被调用时交换两个HasPtr& 类型的对象,运行时会交换HasPtr的数据成员ps和i,这两个成员都是内置的数据类型,会调用标准库的std::swap。而不是调用本身定义的swap,不会导致递归循环
练习13.30:
#include <iostream>
#include <string>
using namespace std;
#include <vector>
class HasPtr {
friend void swap(HasPtr& lhs, HasPtr& rhs);
friend inline void swap(HasPtr& hp1, HasPtr& hp2);
public:
//构造函数分配新的string和计数器,将计数器置为1
HasPtr(const std::string& s = std::string()): ps(new std::string(s)),i(0),use(new std::size_t(1)) { }
//拷贝构造函数拷贝所有三个数据成员,并递增计数器
HasPtr(const HasPtr& p) :ps(p.ps), i(p.i), use(p.use) { ++* use; }
HasPtr& operator=(const HasPtr&);
//定义读取ps的成员函数
string& getPsValue();
~HasPtr();
private:
std::string* ps;
int i;
//记录有多少个对象共享*ps的成员
std::size_t* use;
};
HasPtr::~HasPtr()
{
if (-- * use == 0)
{
delete ps;
delete use;
}
}
HasPtr& HasPtr::operator=(const HasPtr& rhs)
{
++* rhs.use;
if (-- * use == 0)
{
delete ps;
delete use;
}
ps = rhs.ps;
i = rhs.i;
use = rhs.use;
return *this;
}
//定义解引用
string& HasPtr::getPsValue()
{
return *ps;
}
//定义为内联函数
inline void swap(HasPtr& hp1, HasPtr& hp2)
{
cout << "swap hp1 and hp2......................" << endl;
using std::swap;
swap(hp1.ps, hp2.ps);
swap(hp1.i, hp2.i);
swap(hp1.use, hp2.use);
}
int main()
{
//测试,i都被初始化0,无需测试
HasPtr hp1("hello");
HasPtr hp2("world");
cout << "before swap: " << endl;
cout << "hp1: " << hp1.getPsValue()<< endl;
cout << "hp2: " << hp2.getPsValue() << endl;
cout << endl;
//交换hp1和hp2
swap(hp1, hp2);
cout << endl;
cout << "after swap: " << endl;
cout << "hp1: " << hp1.getPsValue() << endl;
cout << "hp2: " << hp2.getPsValue() << endl;
system("pause");
return 0;
}
测试结果:
练习13.31:
#include <iostream>
#include <string>
using namespace std;
#include <vector>
#include <algorithm>
class HasPtr {
friend void swap(HasPtr& lhs, HasPtr& rhs);
friend inline void swap(HasPtr& hp1, HasPtr& hp2);
public:
//构造函数分配新的string和计数器,将计数器置为1
HasPtr(const std::string& s = std::string()): ps(new std::string(s)),i(0),use(new std::size_t(1)) { }
//拷贝构造函数拷贝所有三个数据成员,并递增计数器
HasPtr(const HasPtr& p) :ps(p.ps), i(p.i), use(p.use) { ++* use; }
HasPtr& operator=(const HasPtr&);
//定义<运算符
bool operator<(const HasPtr&);
//定义读取ps的成员函数
string& getPsValue();
~HasPtr();
private:
std::string* ps;
int i;
//记录有多少个对象共享*ps的成员
std::size_t* use;
};
HasPtr::~HasPtr()
{
if (-- * use == 0)
{
delete ps;
delete use;
}
}
HasPtr& HasPtr::operator=(const HasPtr& rhs)
{
++* rhs.use;
if (-- * use == 0)
{
delete ps;
delete use;
}
ps = rhs.ps;
i = rhs.i;
use = rhs.use;
return *this;
}
string& HasPtr::getPsValue()
{
return *ps;
}
//定义<运算符
bool HasPtr::operator<(const HasPtr& hp)
{
return *ps < *hp.ps;
}
//定义为内联函数
inline void swap(HasPtr& hp1, HasPtr& hp2)
{
cout << "swap hp1 and hp2......................" << endl;
using std::swap;
swap(hp1.ps, hp2.ps);
swap(hp1.i, hp2.i);
swap(hp1.use, hp2.use);
}
int main()
{
//定义HasPtr的vector
vector<HasPtr>v;
HasPtr h1("hello");
v.push_back(h1);
HasPtr h2("c++");
v.push_back(h2);
HasPtr h3("world");
v.push_back(h3);
HasPtr h4("fuck");
v.push_back(h4);
HasPtr h5("blue");
v.push_back(h5);
HasPtr h6("what");
v.push_back(h6);
cout << "before sort:" << endl;
for (HasPtr& hp : v)
{
cout << hp.getPsValue() << endl;
}
sort(v.begin(), v.end());
cout << endl;
cout << "after sort:" << endl;
for (HasPtr& hp : v)
{
cout << hp.getPsValue() << endl;
}
system("pause");
return 0;
}
结果:
练习13.32:
swap两个HasPtr类型会交换对象的ps和i数据,use数据都是先减1再加1,不变,ps和i都是内置数据类型,使用标准库的默认swap就可以处理该类型的交换,所以使用自己的swap并不会有什么益处。