13.29 swap(HasPtr&, HasPtr&)函数中调换的ps和i都是内置类型,会调用标准库std::swap,不会导致递归循环。
13.30 代码如下(operator=用swap实现):
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace::std;
class HasPtr {
friend void swap(HasPtr&, HasPtr&);
public:
HasPtr(const string &s = string()):
ps(new string(s)), i(0), use(new size_t(1)) { }
HasPtr(const HasPtr &p):
ps(new string(*p.ps)), i(p.i), use(p.use) { ++*use; }
HasPtr& operator=(HasPtr);
void str() {
cout << *ps << endl;
}
~HasPtr();
private:
string *ps;
int i;
size_t *use;
};
inline
void swap(HasPtr &lhs, HasPtr &rhs)
{
using std::swap;
cout << "swap function" << endl;
swap(lhs.ps, rhs.ps);
swap(lhs.i, rhs.i);
}
HasPtr&
HasPtr::operator=(HasPtr rhs)
{
swap(*this, rhs);
return *this;
}
HasPtr::~HasPtr()
{
if ( --*use == 0 ) {
delete ps;
delete use;
}
}
int main(int argc, char *argv[])
{
HasPtr h1("dog");
HasPtr h2("cat");
HasPtr h3("rat");
h1.str();
h2.str();
h2 = h1;
h2.str();
swap(h1, h3);
h1.str();
h3.str();
return 0;
}
13.31 代码如下:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace::std;
class HasPtr {
friend void swap(HasPtr&, HasPtr&);
public:
HasPtr(const string &s = string()):
ps(new string(s)), i(0), use(new size_t(1)) { }
HasPtr(const HasPtr &p):
ps(new string(*p.ps)), i(p.i), use(p.use) { ++*use; }
HasPtr& operator=(HasPtr);
bool operator<(const HasPtr&);
void str() {
cout << *ps << endl;
}
~HasPtr();
private:
string *ps;
int i;
size_t *use;
};
inline
void swap(HasPtr &lhs, HasPtr &rhs)
{
using std::swap;
cout << "swap function" << endl;
swap(lhs.ps, rhs.ps);
swap(lhs.i, rhs.i);
}
HasPtr&
HasPtr::operator=(HasPtr rhs)
{
swap(*this, rhs);
return *this;
}
bool
HasPtr::operator<(const HasPtr &rhs)
{
return *ps < *rhs.ps;
}
HasPtr::~HasPtr()
{
if ( --*use == 0 ) {
delete ps;
delete use;
}
}
int main(int argc, char *argv[])
{
HasPtr h1("dog");
HasPtr h2("cat");
vector<HasPtr> hv = {h1, h2};
for (auto h : hv)
h.str();
cout << "sort "<< endl;
sort(hv.begin(), hv.end());
for (auto h : hv)
h.str();
return 0;
}
13.32 类指针版本的HasPtr也会从swap收益,如上2题的代码所示,其赋值运算符也可以用swap来定义,无需处理use,因为二者互换后引用计数不变,都是先减1后加1。