为何C++代码中首个元素会调用拷贝构造函数?
为什么第一个emplace_back会调用拷贝构造函数?
先看你的代码:
#include <iostream> #include <string> #include <vector> struct Vertex { float x, y, z; Vertex(float x, float y, float z) : x(x), y(y), z(z) { std::cout << "Created Vertex!" << std::endl; } Vertex(const Vertex& v) // Copy constructor : x(v.x), y(v.y), z(v.z) { std::cout << "Copied!" << std::endl; } }; std::ostream& operator<<(std::ostream& stream, const Vertex& _v) // Overloading operator<< { stream << _v.x << ", " << _v.y << ", " << _v.z; return stream; } int main() { std::vector<Vertex> vertices; vertices.reserve(3); vertices.emplace_back(Vertex(1, 2, 3)); // 1st assignment vertices.emplace_back(4, 5, 6); vertices.emplace_back(7, 8, 9); return 0; }
核心原因在于emplace_back的参数传递逻辑:
- 第一个调用:你手动构造了一个临时
Vertex对象Vertex(1,2,3),这会先触发普通构造函数输出"Created Vertex!"。此时emplace_back接收的是一个现成的Vertex实例,它只能把这个临时对象拷贝到vector预留的内存空间里,因此会调用拷贝构造函数输出"Copied!"。 - 后两个调用:你直接传递了构造
Vertex所需的三个float参数。emplace_back的核心能力就是直接在容器的内存区域内,用传入的参数原地构造对象——它会直接调用Vertex(float, float, float)构造函数,不需要先创建临时对象再拷贝,所以只会输出"Created Vertex!",不会触发拷贝构造。
补充:如果给Vertex定义了移动构造函数,第一个调用会触发移动而非拷贝,但因为你没定义移动构造,编译器会 fallback 到拷贝构造。不过本质问题还是你手动创建了临时对象,违背了emplace_back原地构造的设计初衷。
内容的提问来源于stack exchange,提问作者cpp_newbie
相关产品推荐
相关产品推荐

