C++中for_each循环未调用Copy constructor的原因及相关问题
问题解答
为什么p = Point(++count, count)没调用拷贝构造函数?
你这里的操作是赋值运算,和拷贝构造的触发场景完全不同:
- 拷贝构造函数(
Point(const Point&))仅在创建新对象时生效,比如Point a = b或Point a(b)这类初始化场景。 - 而
p = Point(...)是给vector里已经存在的p(提前用默认构造创建好的对象)赋值,触发的是赋值运算符。因为右边是临时对象(右值),编译器会优先调用默认移动赋值运算符——你没显式定义这个运算符,编译器会自动生成一个,所以不会走拷贝构造,自然看不到copy constructed的输出。
输出里的5次paramterized constructor,是每次创建临时对象Point(++count, count)时触发的,和拷贝构造无关。
为什么删除移动构造后,auto l = Point(5,6)会报错?
当你显式删除移动构造函数(比如Point(Point&&) = delete;),会触发以下逻辑:
- 正常编译优化下,
auto l = Point(5,6)这种拷贝初始化会被编译器通过**返回值优化(NRVO)**直接在l的内存位置构造对象,不需要移动或拷贝。但如果关闭了编译器优化(比如用-O0编译),或者编译器未触发该优化,就会尝试用移动构造函数把临时对象转移给l。 - 你删除了移动构造函数,相当于告诉编译器“禁止移动该类型对象”,此时编译器不会回退到拷贝构造函数,而是直接报错——这就是你看到错误的核心原因。
补充:如果只定义了拷贝构造,编译器不会自动生成移动构造/移动赋值;但显式删除移动构造后,所有需要移动语义的场景都会直接失效。
你的代码
#include <iostream> #include <vector> #include <algorithm> using namespace std; class Point { int x; int y; public: Point (int x, int y):x (x), y (y) { cout << "paramterized constructor" << endl; } Point () = default; Point (const Point & p) { cout << "copy constructed" << endl; x = p.x; y = p.y; } void print () const { cout << x << " " << y << endl; } }; int main () { std::vector < Point > my (5); cout << "vector created" << endl; int count = 0; auto l = Point (5, 6);//RH paramterized constructed and then copy constructed to left? std::for_each (my.begin (), my.end (),[&](Point & p) { p = Point (++count, count);//p not copy constructed? count++; }); std::for_each (my.begin (), my.end (),[](const Point & p) { p.print (); }); return 0; }
输出
default constructor default constructor default constructor default constructor default constructor vector created paramterized constructor copy constructed paramterized constructor paramterized constructor paramterized constructor paramterized constructor paramterized constructor 1 0 3 2 5 4 7 6 9 8
内容的提问来源于stack exchange,提问作者Arul Moondra
相关产品推荐
相关产品推荐

