为什么复制构造函数与移动构造函数一起调用?
Why Copy constructor is called along with Move Constructor?
这个问题看起来很奇怪,但我已经检查了多个编译器。在我的代码中,我有一个Move Constructor
和一个copy constructor
class A {
int val;
public:
A(int var) : val(var) {
}
A( A && a1) {
cout<<"M Value -> "<<a1.val<<endl;
cout<<"Move Cons..."<<endl;
}
A(const A & a1) {
cout<<"Copy Cons.."<<endl;
cout<<"Value -> "<<a1.val<<endl;
}
};
如果我将main
函数写为
int main()
{
vector<A> v1;
A a2(200);
v1.push_back(move(a2));
}
输出为
M Value -> 200
Move Cons...
这是意料之中的,但是如果我将main
函数更改为
int main()
{
vector<A> v1;
A a2(200);
v1.push_back(A(100));
v1.push_back(move(a2));
}
我得到以下输出
M Value -> 100
Move Cons...
M Value -> 200
Move Cons...
Copy Cons.. // unexpected
Value -> 0 // unexpected
谁能帮助我了解这个copy constructor
在哪里以及如何被称为......这也具有价值0
谢谢
原因已经在评论中回答了。 我将尝试说明正在发生的事情。
步骤:
vector<A> v1;
- 矢量的分配。它在内部为一个元素保留空间。
v1.push_back(A(100));
- 构造和向量内
A(100)
的移动。
v1.push_back(move(a2));
- 由于您正在尝试插入一个新元素,超过实际最大大小,因此将其重新分配给新的内存空间。请记住,
std::vector
将其内容保存在连续内存中。 - 在
v1
内移动a2
。 - 将原始
v1
的其余元素(在本例中仅为第一个)复制到新v1
。
记忆:
1) ## v1[undef ] #########################
2) ## v1[A(100)] #########################
3) ## [A(100)] ### v1[undef, undef ] ##
4) ## [A(100)] ### v1[undef, A(200)] ##
5) ## [A(100)] ### v1[A(100), A(200)] ##
附加说明:
与值 0 相关,这是因为这些复制和移动构造函数实际上什么都不做,并且val
值仍未定义。 使用正确的构造函数,此日志应为 100。
如果将移动构造函数标记为noexcept
,它将在重新分配过程中使用,而不是复制过程。
您可以使用v1.emplace_back(100)
而不是v1.push_back(A(100))
避免移动。
相关文章:
- 获取从C++中同一类中的构造函数调用的方法返回的值
- 从具有按值捕获的 lambda 移动构造 std::函数时,移动构造函数调用两次
- 确保所有构造函数调用相同的函数 c++ 设计模式
- 减少复制构造函数调用
- 使用回调函数从构造函数调用虚拟/派生方法的替代方法?
- 在 Google 测试中,我可以从构造函数调用 GetParam() 吗?
- C++ - 从另一个类构造函数调用类构造函数
- 在C++中初始化带有和不使用构造函数调用的对象有什么区别
- 是否可以从移动构造函数调用默认构造函数?
- 在模板生成器模式中分解重复的构造函数调用
- std::atexit 从全局对象的构造函数调用时的排序
- 对构造函数调用的约束
- 编译器错过了无效的构造函数调用,并调用不存在的(或私有的)默认构造函数
- 用构造函数调用填充向量
- 创建指针时是否没有构造函数调用
- 使用 emplace_back 避免移动构造函数调用的最佳方法?
- C++ 抽象类构造函数调用
- 为什么函数参数将带有参数的构造函数调用
- 为什么比“构造函数”调用更多的“解构器”调用
- 将对象传递给函数并不是导致构造函数调用