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; |
| |
| A a1("a1"); |
| A a2("a2"); |
| arr.push_back(a1); |
| |
| arr.push_back(std::move(a2)); |
| cout << "capacity: " << arr.capacity() << endl; |
| |
| 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 |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现