vector的push_back与emplace_back

push_back与emplace_back

#include <iostream>
#include <vector>
using namespace std;
class A {
public:
A() = default;
A(string name) : _name(name) { cout << "ctor: " << _name << endl; }
~A() { cout << "dtor: " << _name << endl; }
// 拷贝构造函数
A(const A &other) { _name += "cp-" + other._name; cout << "cp-ctor: " << _name << endl; }
// 赋值运算符
A& operator=(const A &other) {
if (this != &other) {
_name += "cp-" + other._name;
cout << "cp-op: " << _name << endl;
}
return *this;
}
// 移动构造函数
A(A &&other) noexcept { _name += "mv-" + other._name; cout << "mv-ctor: " << _name << endl; }
// 移动赋值运算符
A& operator=(A &&other) noexcept {
if (this != &other) {
_name += "mv-" + other._name;
cout << "mv-op: " << _name << endl;
}
return *this;
}
string _name;
};
int main()
{
vector<A> arr;
arr.reserve(100); // 重要!重新分配内存时可能导致测试结果有迷惑性
printf("==== push_back(\"a1\") ====\n");
arr.push_back(string("a1"));
printf("\n==== emplace_back(\"a2\") ====\n");
arr.emplace_back(string("a2"));
printf("\n==== push_back/emplace_back(lvalue) ====\n");
A a3("a3");
arr.push_back(a3);
arr.emplace_back(a3);
printf("\n==== push_back/emplace_back(rvalue) ====\n");
A a4("a4");
arr.push_back(std::move(a4));
A a5("a5");
arr.emplace_back(std::move(a5));
printf("\n==== return ====\n");
return 0;
}

输出为:

==== push_back("a1") ====
ctor: a1
mv-ctor: mv-a1
dtor: a1
==== emplace_back("a2") ====
ctor: a2
==== push_back/emplace_back(lvalue) ====
ctor: a3
cp-ctor: cp-a3
cp-ctor: cp-a3
==== push_back/emplace_back(rvalue) ====
ctor: a4
mv-ctor: mv-a4
ctor: a5
mv-ctor: mv-a5
==== return ====
dtor: a5
dtor: a4
dtor: a3
dtor: mv-a1
dtor: a2
dtor: cp-a3
dtor: cp-a3
dtor: mv-a4
dtor: mv-a5

移动构造函数用noexcept修饰后,vector扩容时才会调用

为什么需要将移动构造函数和移动赋值运算符标记为noexcept

#include <iostream>
#include <vector>
using namespace std;
class A {
public:
A() = default;
A(string name) : _name(name) { cout << "ctor: " << _name << endl; }
~A() { cout << "dtor: " << _name << endl; }
// 拷贝构造函数
A(const A &other) { _name = "cp-" + other._name; cout << "cp-ctor: " << _name << endl; }
// 赋值运算符
A& operator=(const A &other) {
if (this != &other) {
_name = "cp-" + other._name;
cout << "cp-op: " << _name << endl;
}
return *this;
}
// 移动构造函数
A(A &&other) noexcept { _name = "mv-" + other._name; cout << "mv-ctor: " << _name << endl; }
// 移动赋值运算符
A& operator=(A &&other) noexcept {
if (this != &other) {
_name = "mv-" + other._name;
cout << "mv-op: " << _name << endl;
}
return *this;
}
string _name = "anonymous";
};
int main() {
vector<A> arr(4);
arr.reserve(4);
cout << "capacity: " << arr.capacity() << endl; // 4
A a1("a1");
A a2("a2");
arr.push_back(a1); // 触发vector内存的重新分配: 第5个元素调用cp-ctor
// 如果mv-ctor声明为noexcept,则前4个元素调用移动构造函数; 否则调用拷贝构造函数cp-ctor
arr.push_back(std::move(a2)); // 第6个元素调用mv-ctor
cout << "capacity: " << arr.capacity() << endl; // 8
cout << "==== return ====" << endl;
}

输出信息为:

capacity: 4
ctor: a1
ctor: a2
cp-ctor: cp-a1
mv-ctor: mv-anonymous
dtor: anonymous
mv-ctor: mv-anonymous
dtor: anonymous
mv-ctor: mv-anonymous
dtor: anonymous
mv-ctor: mv-anonymous
dtor: anonymous
mv-ctor: mv-a2
capacity: 8
==== return ====
dtor: a2
dtor: a1
dtor: mv-anonymous
dtor: mv-anonymous
dtor: mv-anonymous
dtor: mv-anonymous
dtor: cp-a1
dtor: mv-a2
posted @   devin1024  阅读(50)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示