C ++: 48 --- Operation exchange (swap function is provided a class)

class HasPtr {
public:
    HasPtr(const std::string &s = std::string())
        :ps(new std::string(s)), i(0) {}
    
    HasPtr(const HasPtr& p)  //拷贝构造函数
        :ps(new std::string(*(p.ps))), i(p.i) {}
 
    HasPtr& operator=(const HasPtr& rhs); //拷贝辅助运算符
 
    ~HasPtr() { delete ps; }
private:
    std::string *ps;
    int i;
};

//我们这个operator=可以处理自我赋值的情况
HasPtr& HasPtr::operator=(const HasPtr& rhs)
{
    auto newp = new std::string(*(rhs.ps));
    delete ps; //释放旧内存
    ps = newp; //使用新内存
    i = rhs.i;
    return *this; //返回自身
}

First, why should design swap operation

  • For the above classes HasPtr, if we want to exchange operation two classes, we will then typically performs the following code:
HasPtr v1, v2;

HasPtr temp = v1; //创建一个临时变量保存v1
v1 = v2;          //将v2赋值给v1
v2 = temp;        //将原v1赋值给v2
  • It will perform a copy and two assignments in the code above the code:
    • Copy: copy to temp v1
    • Assigned to the v2 v1, v2 will be assigned to temo
  • For the above and copy assignment operator, will be executed to create string objects internally. The memory allocation is not necessary, we just want to exchange the swap pointer, rather than allocating a new copy of the string. Therefore, in theory, for the above v1 and v2 exchange operation, we only exchange ps pointer on it:
//下面是伪代码,因为ps是private的
HasPtr v1, v2;

string *temp = v1.ps;
v1.ps = v2.ps;
v2.ps = temp;

Second, write your own swap function

  • Now we write a custom version of swap function, implemented as follows:
class HasPtr {
public:
    //其他代码省略(同上)
    friend void swap(HasPtr&, HasPtr&);
};

inline void swap(HasPtr &lhs, HasPtr &rhs)
{
    using std::swap;
    swap(lhs.ps, lhs.ps);//交换指针,而不是string数据
    swap(lhs.i, lhs.i);  //交换int成员
}
  • Function format to explain:
    • friend: Because ps and i are private members, so it needs to be defined as a friend function
    • inline: In order to optimize the code
  • And members of different control copy, swap not necessarily want. However, resources are allocated to the class definition swap can be a very important tool

Third, call swap custom, instead of std :: swap

  • Standard Template Library std swpa also defines a function, so the call swap custom function when necessary to prevent conflict with std :: swap
  • Now suppose a class Foo, which has a class HasPtr
class HasPtr {};

class Foo
{
public:
    HasPtr ptr;
};

void swap(Foo &lhs, Foo &rhs)
{
    std::swap(lhs.ptr, rhs.ptr); //此处调用的是std::swap,没有调用我们自定义的swpa函数
}
  • So we need to modify the code to call our above-defined function swap
void swap(Foo &lhs, Foo &rhs)
{
    using std::swap;
    swap(lhs.ptr, rhs.ptr); //使用HasPtr版本的swap函数
}

Fourth, the use of the assignment operator in swap

  • Classes defined swap swap usually define their assignment operator. The operator uses a technique called copy and exchange
  • code show as below:
class HasPtr {
public:
    //其他代码同上
    HasPtr& operator=(HasPtr rhs);
};

HasPtr& HasPtr::operator=(HasPtr rhs)
{
    //交换左侧对象和局部变量rhs的内容
    swap(*this, rhs); //rhs现在只想本对象增使用的内存
    return *this;
}//函数结束后,rhs析构,释放rhs中的指针(本对象原来使用的)
  • This technology went in that:
    • It automatically handles the case of self-assignment is a natural and safe
    • By copying it to the right before changing the left operand think about ensuring the right of self-evaluation, which is consistent with the methods we used in the original assignment operator in
    • It guarantees a secure method is the same as the original assignment operator to achieve
    • The only possible exception is thrown in the code is a copy constructor new expression. If an exception does occur, it will occur before we change the left of the object
  • And switching copied using the assignment operator is automatically exception safety, and can correctly handle the self-assignment
  • This type of operator we will explain later in the article: https://blog.csdn.net/qq_41453285/article/details/104419356
Released 1481 original articles · won praise 1026 · Views 380,000 +

Guess you like

Origin blog.csdn.net/qq_41453285/article/details/104426758