C++中的复制和交换习惯用法

在深入研究之前,让我们先看看我们使用的普通“重载赋值运算符”。

null

// Simple C++ program to demonstrate overloading of
// assignment operator.
#include <iostream>
#include <cstring>
using namespace std;
class anyArrayClass
{
int size;
int *ptr;
public :
// Initializer list
anyArrayClass( int s=0):size(s),
ptr(size? new int [size]:nullptr) {}
// Copy constructor
anyArrayClass( const anyArrayClass& obj):size(obj.size),
ptr(size? new int [size]:nullptr)
{
memmove (ptr, obj.ptr, size* sizeof ( int ));
}
// Overloaded assignment operator
anyArrayClass& operator=( const anyArrayClass& obj)
{
// self assignment check
if ( this != &obj)
{
delete ptr;
size = obj.size;
ptr = size? new int [size]: nullptr;
memmove (ptr, obj.ptr, size* sizeof ( int ));
return * this ;
}
}
~anyArrayClass()
{
delete [] ptr;
}
}


上述赋值运算符执行以下操作: 1.自我分配检查。 2.如果分配给自己的不是自己,那么它会执行以下操作。 a) 释放分配给此->ptr的内存 b) 为该->ptr分配新内存并复制值 c) 归还这个

上述方法的缺点:

  1. 自我分配检查:自我分配很少进行,因此自我分配检查在大多数情况下都不相关。这只会减慢代码的速度。
  2. 内存释放和分配:可以看到,首先释放内存(让指针悬空),然后分配新的内存块。现在,如果由于某种原因,内存没有分配,并且抛出了一个异常,那么“this->ptr”将悬空指向一个释放的内存。场景应该是,要么分配成功,要么对象根本不应该被改变。

下面是复制和交换方法的作用。这种方法优雅地解决了上述问题,还提供了代码可重用性的范围。让我们看看到底是什么。

考虑下面的代码:

// Simple C++ program to demonstrate use of copy-and-swap
// idiom by improving above code.
#include <iostream>
#include <cstring>
using namespace std;
class anyArrayClass
{
int size;
int *ptr;
public :
anyArrayClass( int s=0):size(s),
ptr(size? new int [size]:nullptr) {}
// Copy constructor
anyArrayClass( const anyArrayClass& obj):size(obj.size),
ptr(size? new int [size]:nullptr)
{
memmove (ptr, obj.ptr, size* sizeof ( int ));
}
friend void swap(anyArrayClass& obj1, anyArrayClass& obj2)
{
std::swap(obj1.size, obj2.size);
std::swap(obj1.ptr, obj2.ptr);
}
// overloaded assignment operator
// argument passed by value. calls copy ctor
anyArrayClass& operator=(anyArrayClass obj)
{
// calling friend function
swap(* this , obj);
return * this ;
}
~anyArrayClass()
{
delete [] ptr;
}
}


在上面的示例中,“operator=()”的参数由调用copy构造函数的值传递,以创建“operator=()”本地的anyArrayClass对象。然后将临时对象的值与“*this”对象交换(赋值运算符调用的LHS)。

优势:

  1. 由于参数是按值传递的,因此无需进行更多的自分配检查(这意味着无需进行更多内存释放)。此外,由于自分配非常罕见,因此在自分配的情况下复制的开销应该不是问题。
  2. 现在,由于复制构造函数用于创建临时对象,因此,只有在创建临时对象时,才会进行交换。基本上,我们在这里手工做的,是编译器在这里为我们做的。
  3. 代码可重用性:正如我们看到的那样,’operator=()’的主体中没有太多代码,我们使用复制构造函数和交换函数来完成这项工作。

本文由 比什瓦·纳特 .如果你喜欢GeekSforgek,并想贡献自己的力量,你也可以使用 贡献极客。组织 或者把你的文章寄到contribute@geeksforgeeks.org.看到你的文章出现在Geeksforgeks主页上,并帮助其他极客。

如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写下评论。

© 版权声明
THE END
喜欢就支持一下吧
点赞10 分享