我写了一个简单的矢量程序,在其中我得到了以下输出。你能帮我理解它的输出吗?

I have written one simple vector program in which i am getting following output. Can you help me to understand it's output?

本文关键字:输出 在其中 一个 简单 程序      更新时间:2023-10-16

以下是带有输出的代码片段。

#include<iostream>
#include<vector>
using namespace std;
class VectDemo
{
public:
VectDemo()
{
cout<<"Contructor"<<endl;
}
~VectDemo()
{
cout<<"Destructor"<<endl;
}
};
int main()
{
vector<VectDemo> VectOfObj;
cout<<"Size = "<<VectOfObj.size()<<endl;
for(int i= 0;i<2;i++)
{
VectOfObj.push_back(VectDemo());
}
cout<<"Size = "<<VectOfObj.size()<<endl;
cout<<"Capacity = "<<VectOfObj.capacity()<<endl;
return 0;
}

输出: 大小 = 0

构造器

破坏者

构造器

破坏者

破坏者

大小 = 2

容量 = 2

破坏者

破坏者

构造函数和析构函数日志消息不平衡,因为VectDemo没有记录正在调用的复制构造函数。VectOfObj.push_back(VectDemo())创建一个临时VectDemo对象,然后必须将其复制到矢量中。此外,当向量的capacity增长时,矢量的元素也会被复制。在构造副本时不记录,仅在销毁副本时进行日志记录。

试试这个:

#include<iostream>
#include<vector>
using namespace std;
char nextID = 'A';
class VectDemo
{
public:
char id;
VectDemo()
{
id = nextID++;
cout<<"Default Constructor "<<id<<endl;
}
VectDemo(const VectDemo &src)
{
id = nextID++;
cout<<"Copy Constructor "<<src.id<<"->"<<id<<endl;
}
~VectDemo()
{
cout<<"Destructor "<<id<<endl;
}
};
int main()
{
vector<VectDemo> VectOfObj;
cout<<"Before Loop"<<endl;
cout<<"Size = "<<VectOfObj.size()<<" Capacity = "<<VectOfObj.capacity()<<endl;
cout<<"Entering Loop"<<endl;
for(int i= 1;i<=2;i++)
{
cout<<"push_back #"<<i<<endl;
VectOfObj.push_back(VectDemo());
}
cout<<"After Loop"<<endl;
cout<<"Size = "<<VectOfObj.size()<<" Capacity = "<<VectOfObj.capacity()<<endl;
return 0;
}

输出:

Before Loop
Size = 0 Capacity = 0
Entering Loop
push_back #1
Default Constructor A // temp created
Copy Constructor A->B // VectOfObj[0] created from temp
Destructor A          // temp destroyed
push_back #2
Default Constructor C // temp created
Copy Constructor C->D // VectOfObj[1] created from temp
Copy Constructor B->E // new VectOfObj[0] created from old VectOfObj[0]
Destructor B          // old VectOfObj[0] destroyed
Destructor C          // temp destroyed
After Loop
Size = 2 Capacity = 2
Destructor E          // VectOfObj[1] destroyed
Destructor D          // VectOfObj[0] destroyed

现场演示

如果您使用的是 C++11 或更高版本,则添加移动构造函数会稍微改变一些内容:

#include<iostream>
#include<vector>
using namespace std;
char nextID = 'A';
class VectDemo
{
public:
char id;
VectDemo()
{
id = nextID++;
cout<<"Default Constructor "<<id<<endl;
}
VectDemo(const VectDemo &src)
{
id = nextID++;
cout<<"Copy Constructor "<<src.id<<"->"<<id<<endl;
}
VectDemo(VectDemo &&src)
{
id = nextID++;
cout<<"Move Constructor "<<src.id<<"->"<<id<<endl;
}
~VectDemo()
{
cout<<"Destructor "<<id<<endl;
}
};
int main()
{
vector<VectDemo> VectOfObj;
cout<<"Before Loop"<<endl;
cout<<"Size = "<<VectOfObj.size()<<" Capacity = "<<VectOfObj.capacity()<<endl;
cout<<"Entering Loop"<<endl;
for(int i= 1;i<=2;i++)
{
cout<<"push_back #"<<i<<endl;
VectOfObj.push_back(VectDemo());
}
cout<<"After Loop"<<endl;
cout<<"Size = "<<VectOfObj.size()<<" Capacity = "<<VectOfObj.capacity()<<endl;
return 0;
}

输出

Before Loop
Size = 0 Capacity = 0
Entering Loop
push_back #1
Default Constructor A // temp created
Move Constructor A->B // VectOfObj[0] created from temp
Destructor A          // temp destroyed
push_back #2
Default Constructor C // temp created
Move Constructor C->D // VectOfObj[1] created from temp
Copy Constructor B->E // new VectOfObj[0] created from old VectOfObj[0]
Destructor B          // old VectOfObj[0] destroyed
Destructor C          // temp destroyed
After Loop
Size = 2 Capacity = 2
Destructor E          // VectOfObj[1] destroyed
Destructor D          // VectOfObj[0] destroyed

现场演示

而且,正如@walnut提到的,如果你将移动构造函数标记为noexcept,编译器可以进一步优化一个push_back(),使向量capacity增长,并且输出略有变化:

#include<iostream>
#include<vector>
using namespace std;
char nextID = 'A';
class VectDemo
{
public:
char id;
VectDemo()
{
id = nextID++;
cout<<"Default Constructor "<<id<<endl;
}
VectDemo(const VectDemo &src)
{
id = nextID++;
cout<<"Copy Constructor "<<src.id<<"->"<<id<<endl;
}
VectDemo(VectDemo &&src) noexcept
{
id = nextID++;
cout<<"Move Constructor "<<src.id<<"->"<<id<<endl;
}
~VectDemo()
{
cout<<"Destructor "<<id<<endl;
}
};
int main()
{
vector<VectDemo> VectOfObj;
cout<<"Before Loop"<<endl;
cout<<"Size = "<<VectOfObj.size()<<" Capacity = "<<VectOfObj.capacity()<<endl;
cout<<"Entering Loop"<<endl;
for(int i= 1;i<=2;i++)
{
cout<<"push_back #"<<i<<endl;
VectOfObj.push_back(VectDemo());
}
cout<<"After Loop"<<endl;
cout<<"Size = "<<VectOfObj.size()<<" Capacity = "<<VectOfObj.capacity()<<endl;
return 0;
}

输出

Before Loop
Size = 0 Capacity = 0
Entering Loop
push_back #1
Default Constructor A // temp created
Move Constructor A->B // VectOfObj[0] created from temp
Destructor A          // temp destroyed
push_back #2
Default Constructor C // temp created
Move Constructor C->D // VectOfObj[1] created from temp
Move Constructor B->E // new VectOfObj[0] created from old VectOfObj[0]
Destructor B          // old VectOfObj[0] destroyed
Destructor C          // temp destroyed
After Loop
Size = 2 Capacity = 2
Destructor E          // VectOfObj[1] destroyed
Destructor D          // VectOfObj[0] destroyed

现场演示

相关文章: