1. 基本介绍
std::swap
是C++标准库中的实用函数,位于 <utility>
头文件中(C++11之前在 <algorithm>
),用于交换两个对象的值。
2. 函数原型
template< class T >
void swap( T& a, T& b ) noexcept;
3. 基本用法
#include <iostream>
#include <utility> // 包含swap函数
int main() {
int a = 10, b = 20;
std::cout << "交换前: a = " << a << ", b = " << b << std::endl;
std::swap(a, b);
std::cout << "交换后: a = " << a << ", b = " << b << std::endl;
return 0;
}
4. 自定义类型交换
可以为自定义类型实现特化的swap函数:
#include <iostream>
#include <utility>
class MyClass {
public:
int value;
MyClass(int v) : value(v) {}
// 自定义swap函数
friend void swap(MyClass& first, MyClass& second) {
std::swap(first.value, second.value);
}
};
int main() {
MyClass obj1(100), obj2(200);
std::cout << "交换前: obj1 = " << obj1.value
<< ", obj2 = " << obj2.value << std::endl;
swap(obj1, obj2); // 调用自定义swap
std::cout << "交换后: obj1 = " << obj1.value
<< ", obj2 = " << obj2.value << std::endl;
return 0;
}
5. 移动语义优化(C++11及以上)
#include <iostream>
#include <utility>
class Resource {
int* data;
public:
Resource(int size) : data(new int[size]) {}
~Resource() { delete[] data; }
// 移动构造函数
Resource(Resource&& other) noexcept : data(other.data) {
other.data = nullptr;
}
// 移动赋值运算符
Resource& operator=(Resource&& other) noexcept {
if (this != &other) {
delete[] data;
data = other.data;
other.data = nullptr;
}
return *this;
}
friend void swap(Resource& a, Resource& b) noexcept {
using std::swap;
swap(a.data, b.data);
}
};
6. 数组交换
#include <iostream>
#include <utility>
int main() {
int arr1[5] = {1,2,3,4,5};
int arr2[5] = {6,7,8,9,10};
std::swap(arr1, arr2); // 交换整个数组
for(int i=0; i<5; ++i) {
std::cout << arr1[i] << " ";
}
std::cout << std::endl;
return 0;
}
7. 性能特点
- 对于基本类型,性能等同于手动交换
- 对于自定义类型,使用移动语义可以避免不必要的拷贝
- 对于标准容器(如std::vector),交换操作是O(1)复杂度
8. 最佳实践
- 为自定义类型实现swap函数
- 使用ADL(参数依赖查找)调用swap:
using std::swap;
swap(a, b); // 会优先查找自定义swap
- 在实现赋值运算符时使用swap技巧:
MyClass& operator=(MyClass other) {
swap(*this, other);
return *this;
}
9. 注意事项
- 确保交换的对象类型相同
- 对于大型对象,使用移动语义优化性能
- 在C++11及以上版本中,swap被标记为noexcept