有了代码,我有以下输出:
A::A() is called
test #1
A::A(const A & other) is called
test #2
A::A(const A & other) is called
A::A(const A & other) is called
test #3
A::A(const A & other) is called
A::A(const A & other) is called
A::A(const A & other) is called
Run Code Online (Sandbox Code Playgroud)
在调试代码时,对于3个测试用例,我发现第一次复制构造函数的调用是相同的(我认为这是有意义的):制作对象的副本并推送到向量.
但是,通过"_Umove_if_noexcept"对复制构造函数进行额外调用.
对于测试#2,当vec已经有一个条目时,它将进一步调用复制构造函数的一次.
对于测试#3,当vec已经有两个条目时,它将进一步调用复制构造函数的两倍.
这在Visual Studio 2017和gcc 5.4.0上是可重现的.
为什么会这样?是否存在性能问题?
谢谢
#include <iostream>
#include <vector>
class A
{
public:
//constructor
A()
{
a = 10;
std::cout << "A::A() is called" << std::endl;
}
//copy constructor
A(const A& other) : a(other.a)
{
std::cout << "A::A(const A & other) is called" << std::endl;
}
//assignment operator
A& operator=(const A& other)
{
std::cout << "A::operator=(const A & other) is called" << std::endl;
a = other.a;
return *this;
}
public:
int a;
};
int main()
{
std::vector<A> vec;
//A::A() is called
A a;
std::cout << "test #1" << std::endl;
//A::A(const A & other) is called by push_back
vec.push_back(a);
std::cout << "test #2" << std::endl;
//A::A(const A & other) is called
//A::A(const A & other) is called from _Umove_if_noexcept
vec.push_back(a);
std::cout << "test #3" << std::endl;
//A::A(const A & other) is called
//A::A(const A & other) is called from _Umove_if_noexcept
//A::A(const A & other) is called from _Umove_if_noexcept
vec.push_back(a);
std::cin.get();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
第一个副本是明确的 - push_back()需要复制对象.
在第二个副本中,发生了两件事: