在擦除过程中对构造函数调用的输出感到困惑。
#include <iostream>
#include <vector>
using namespace std;
class sample
{
public:
sample(){ cout<<"Deafult cons\n";}
sample( int a) { cout<<"Param Cons\n"; }
sample( const sample& Obj ) { cout<<"Copy called\n";}
sample( sample &&objj) { cout<<"Copy Reference cons \n";}
sample& operator=(sample&& other){ cout<<"Copy equal cons \n";}
sample& operator=(sample& other){ cout<<"Normal equal cons \n";}
~sample() {cout<<"Destroy\n";}
};
int main()
{
vector < sample > Object;
Object.push_back( sample() );
Object.push_back( sample() );
cout<<" ********* Going to call Erase ********** \n";
Object.erase( Object.begin() );
cout<<" ********* End of call Erase ********** \n";
return 0;
}
输出是
聋人理解//理解,创造临时对象
复制参考缺点//理解,移动作业
毁灭//毁坏临时物体
侮辱缺点//构建第二个临时对象
复制参考缺点//将第二个临时转移的参与者移动到矢量
副本叫//在这里,我理解了内存不足,矢量增加了大小并试图复制旧对象
销毁
销毁
*********打电话删除**********
复制平等利弊
销毁
*********结束通话删除**********
毁灭
我的问题,
大小增加后,为什么系统调用COPY Contructor而不是Move assignment operator或Move构造函数来复制/移动旧对象?
Coz调用复制构造函数再次导致性能问题。
如果我错了,请纠正我
答案 0 :(得分:1)
大小增加后,为什么系统调用COPY Contructor而不是Move assignment operator或Move构造函数来复制/移动旧对象?
sample
的移动构造函数未使用,因为它不是noexcept
。
复制构造函数的优点是保留了原始文件。因此,如果在复制期间抛出异常,则可以丢弃到目前为止创建的副本,并且我们可以返回到向量的原始状态。
但是,如果在一系列移动过程中抛出异常,我们已经部分更改了原始值的状态,并且无法轻松恢复原始状态。试图&#34;退回&#34;一些已移动的对象有可能引发更多异常,并可能使其更糟,因此不会尝试。
因此,如果类具有复制构造函数,则优先于可能抛出的移动构造函数。如果班级只是可移动的,但不可复制,则会尝试移动,我们将不得不交叉手指并希望它能够正常工作。否则,我们可能会在异常期间失去一些成员。