std::vector 没有提供容器内元素相互交换的方法,可以自己写一个:
//交换对象的指针,要求传入的是指针 //不会构造新的对象,只临时声明一个指针 template<typename T> void Swap(T* &a, T* &b) { T* temp = a; a = b; b = temp; } //交换对象的内容,要求传入的是对象 //需要构造一个新的 T 类型的 temp 来存放 a template<typename T> void Swap(T &a, T &b) { T temp = a; a = b; b = temp; }
根据代码注释可以知道
void Swap(T* &a, T* &b)
不构造新的对象,而
void Swap(T &a, T &b)
构造新的对象,并且出作用域后析构对象,具体用测试代码说明
class foo {
public:
int val = 0;
foo(int v) {
val = v;
cout << "foo " << val << " constructed\n";
}
foo(const foo& c) {
this->val = c.val;
cout << "foo " << val <<" Copy Constructor called" << endl;
}
~foo() {
cout << "foo " << val << " deleted\n";
}
};
int main()
{
vector<foo*> foo_v;
for (int i = 0; i < 6; i++) {
//不会析构对象,因为是new出来的
//不会在push_back过程中构造对象
foo_v.push_back(new foo(i));
}
//交换对象的指针,不调用构造和析构函数
Swap(foo_v[0], foo_v[3]);
for (int i = 0; i < foo_v.size(); i++) {
std::cout << foo_v[i]->val << endl;
}
vector<foo> foo_v_;
for (int i = 0; i < 3; i++) {
//每push_back一次由于拷贝构造都会构造一次对象
foo_v_.push_back(foo(i));
//每次出作用域都会把foo(i)析构
}
//直接交换对象,会调用一次构造和析构函数
Swap(foo_v_[0], foo_v_[2]);
for (int i = 0; i < foo_v_.size(); i++) {
std::cout << foo_v_[i].val << endl;
}
执行结果如下:
可以看到分割线以上 new 出来的对象 pushback 和 Swap 过程中没有进行拷贝构造的操作,而分割线以下部分在 pushback 和 Swap 过程中进行拷贝构造和析构操作,显然是比较低效的。