C++交换操作

标准库中swap的缺点

如果一个类定义了自己的swap,那么算法将使用类自定义版本,否则算法将使用标准库定义的swap,标准库定义的swap在交换两个对象时需要进行一次拷贝和两次赋值,理论上这些内存分配都是不必要的,我们更希望swap交换指针,而不是分配对象的新副本。

template <class _Ty, class>
inline void swap(_Ty& _Left, _Ty& _Right) _NOEXCEPT_COND(is_nothrow_move_constructible_v<_Ty>&&is_nothrow_move_assignable_v<_Ty>) { // exchange values stored at _Left and _Right_Ty _Tmp = _STD move(_Left);_Left    = _STD move(_Right);_Right   = _STD move(_Tmp);
}
class Person
{
public:const char* name_;Person(const char* name) :name_(name) {std::cout << "call Person::Person(name)" << std::endl;};Person(const Person& person) {//拷贝构造函数std::cout << "call Person::Person(person)" << std::endl;name_ = person.name_;};Person& operator=(const Person& person) {//拷贝赋值运算符std::cout << "call Person::operator=" << std::endl;name_ = person.name_;return *this;}
};int main()
{Person person1{ "xiao hong" };Person person2{ "xiao ming" };swap(person1,person2);system("pause");
}

一次拷贝和两次赋值:

call Person::Person(name)
call Person::Person(name)
call Person::Person(person)
call Person::operator=
call Person::operator=

编写我们自己的swap函数

当有多个重载模板对一个调用提供同样好的匹配时,应选择最特例化的版本,所以下面的代码中我们自定义的swap匹配程度会优于std中定义的版本。

void swap(Person& person1, Person& person2)
{cout<<"swap person"<<endl;swap(person1.name_, person2.name_);
}int main()
{Person person1{ "xiao hong" };Person person2{ "xiao ming" };swap(person1,person2);cout << person1.name_ << endl;//xiao mingcout << person2.name_ << endl;//xiao hongsystem("pause");
}

在赋值运算符中使用swap

定义swap的类通常用swap来定义它们的赋值运算符,这些运算符使用了一种名为拷贝并交换的技术,这种技术将左侧运算对象与右侧运算对象的一个副本进行交换。

在这个版本的赋值运算符中,参数并不是引用,而是右侧运算对象的一个副本,然后我们调用swap交换参数和*this中的数据成员,在赋值运算符结束时,参数被销毁,释放掉了左侧运算对象中原来的内存(如果申请了的话)。

void swap(Person& person1, Person& person2)
{cout<<"swap person"<<endl;swap(person1.name_, person2.name_);
}Person& Person::operator=(Person person) {swap(*this, person);return *this;
}int main()
{Person person1{ "xiao hong" };Person person2{ "xiao ming" };person1 = person2;cout << person1.name_ << endl;//xiao mingcout << person2.name_ << endl;//xiao mingsystem("pause");
}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部