玩命加载中 . . .

13.3-交换操作


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是右侧运算对象的一个副本
赋值函数执行时,交换thisrhs的资源,函数执行完之后,rhs就被销毁了,释放掉左侧运算对象中原来的内存


文章作者: kunpeng
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 kunpeng !
  目录