13.3 交换操作
在排序算法中经常用到两个元素的交换,如果设计的类也要实现排序,就需要用到swap
,如果类没有自定义swap
函数,就会调用标准库定义的swap
标准库的swap
Person tmp = p1;
p1 = p2;
p2 = tmp
其中的两次赋值都要进行动态内存分配,这是没有必要的,只需要交换两个对象的指针就可以了
编写自己的swap函数
string *tmp = p1.ptr;
p1.ptr = p2.ptr;
p2.ptr = tmp;
而指针的交换可以用匹配类型的模板swap
来完成
class Person {
private:
string *ptr;
int age;
public:
friend void swap(Person&, Person&);
};
inline
void swap(Person& lhs, Person& rhs) {
using std::swap;
swap(lhs.ptr, rhs.ptr); // 交换指针变量
swap(lhs.age, rhs.age); // 交换成员变量
}
自定义的swap
不是成员函数,但需要对私有变量进行修改,所以定义为友元函数,并声明为内联函数
在赋值运算符中使用swap
class Person {
private:
string *ptr;
int age;
public:
Person(const string& s = string(), const int n = 0) : ptr(new string(s)), age(n) {}
Person(const Person& p)
: ptr(new string(*p.ptr)), age(p.age)
{
cout << "copy constructor" << endl;
} // 拷贝构造函数
Person& operator=(Person rhs) {
cout << "swap copy assignment" << endl;
swap(*this, rhs);
return *this;
}
~Person() { delete ptr; }
friend void swap(Person &, Person &);
};
inline void swap(Person& lhs, Person& rhs) {
cout << "Person swap" << endl;
using std::swap;
swap(lhs.ptr, rhs.ptr);
swap(lhs.age, rhs.age);
}
int main(int argc, char const *argv[]) {
Person p1("kavin", 23);
Person p2("jack", 34);
p2 = p1;
return 0;
}
// copy constructor 按值传递会调用拷贝构造函数
// swap copy assignment
// Person swap 调用类自定义的swap
这里右侧运算对象以传值方式传递给了赋值运算符,因此,rhs
是右侧运算对象的一个副本
赋值函数执行时,交换this
和rhs
的资源,函数执行完之后,rhs
就被销毁了,释放掉左侧运算对象中原来的内存