我不知道为什么复制构造函数的调用在 C++ 中不稳定
I don't know why the copy constructor's call is erratic in c++
我通过学习来理解 Move 的概念,并且我编写代码来查看复制构造函数调用的差异。
但是尴尬的是拷贝构造函数的调用飘忽不定。
看不懂为什么要这样打印
下面是一个简单的示例代码。
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class A {
private:
string s;
public:
A(string s) : s(s) {}
A(const A& ref) {
s = ref.s;
cout << s << " copy constructor" << endl;
}
friend ostream& operator<<(ostream&, const A&);
};
ostream& operator<<(ostream& os, const A& pos) {
os << pos.s << endl;
return os;
}
int main(void) {
vector<A> v;
v.push_back(A("a"));
v.push_back(A("b"));
v.shrink_to_fit();
cout << &v[0] << " v.capacity() : " << v.capacity() << endl;
v.push_back(A("c"));
v.push_back(A("d"));
cout << &v[0] << " v.capacity() : " << v.capacity() << endl;
cout << v[0] << v[1] << v[2] << v[3] << endl;
cout << "///////////////////////////////////" << endl;
vector<A> v2;
v2.emplace_back(("a"));
v2.emplace_back(("b"));
v2.shrink_to_fit();
cout << &v2[0] << " v.capacity() : " << v2.capacity() << endl;
v2.emplace_back(("c"));
v2.emplace_back(("d"));
cout << &v2[0] << " v.capacity() : " << v2.capacity() << endl;
cout << v2[0] << v2[1] << v2[2] << v2[3] << endl;
return 0;
}
输出:
a copy constructor
b copy constructor
a copy constructor
0073A578 v.capacity() : 2
c copy constructor
a copy constructor
b copy constructor
d copy constructor
a copy constructor
b copy constructor
c copy constructor
0073EFF0 v.capacity() : 4
a
b
c
d
///////////////////////////////////
a copy constructor
0073A578 v.capacity() : 2
a copy constructor
b copy constructor
a copy constructor
b copy constructor
c copy constructor
0073E970 v.capacity() : 4
a
b
c
d
不知道为什么拷贝构造函数调用不稳定
所以。
v.push_back(A("a"));
v.push_back(A("b"));
v.shrink_to_fit();
cout << &v[0] << " v.capacity() : " << v.capacity() << endl;
我对这部分的预期输出是:
a copy constructor
b copy constructor
009A6CA8 v.capacity() : 2
但输出不同
a copy constructor
b copy constructor
a copy constructor
009A6CA8 v.capacity() : 2
我不知道为什么我在这部分又打了一次'a'。
其他人也是如此。有些是重复的,有些不是。
我想看看复制构造函数和移动调用之间的区别。代码有错吗?
如果你想研究移动构造函数,你必须提供一个。具有用户提供的复制构造函数(如您的)的 class 没有移动构造函数,因此不会被移动。因此,它将被复制到原本可以移动的地方。
在输出中
a copy constructor
b copy constructor
a copy constructor
009A6CA8 v.capacity() : 2
第一个a copy constructor
来自A(a)
被复制到向量中。
第二个 a copy constructor
是因为矢量 resizing。当您压入第二个元素时,向量将调整大小,这可能包括分配新内存并将旧元素复制到新内存中。
尝试在第一个 push_back
之前打印 capacity
并在第一个 和第二个 push_back
之间打印 (没有任何 shrink_to_fit
).您会看到容量从 0
到 1
再到 2
。容量的每次增加都是一个新的分配,它将复制所有现有元素(但是从 0
到 1
向量中没有元素,因此不会复制任何内容)。
我通过学习来理解 Move 的概念,并且我编写代码来查看复制构造函数调用的差异。
但是尴尬的是拷贝构造函数的调用飘忽不定。 看不懂为什么要这样打印
下面是一个简单的示例代码。
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class A {
private:
string s;
public:
A(string s) : s(s) {}
A(const A& ref) {
s = ref.s;
cout << s << " copy constructor" << endl;
}
friend ostream& operator<<(ostream&, const A&);
};
ostream& operator<<(ostream& os, const A& pos) {
os << pos.s << endl;
return os;
}
int main(void) {
vector<A> v;
v.push_back(A("a"));
v.push_back(A("b"));
v.shrink_to_fit();
cout << &v[0] << " v.capacity() : " << v.capacity() << endl;
v.push_back(A("c"));
v.push_back(A("d"));
cout << &v[0] << " v.capacity() : " << v.capacity() << endl;
cout << v[0] << v[1] << v[2] << v[3] << endl;
cout << "///////////////////////////////////" << endl;
vector<A> v2;
v2.emplace_back(("a"));
v2.emplace_back(("b"));
v2.shrink_to_fit();
cout << &v2[0] << " v.capacity() : " << v2.capacity() << endl;
v2.emplace_back(("c"));
v2.emplace_back(("d"));
cout << &v2[0] << " v.capacity() : " << v2.capacity() << endl;
cout << v2[0] << v2[1] << v2[2] << v2[3] << endl;
return 0;
}
输出:
a copy constructor
b copy constructor
a copy constructor
0073A578 v.capacity() : 2
c copy constructor
a copy constructor
b copy constructor
d copy constructor
a copy constructor
b copy constructor
c copy constructor
0073EFF0 v.capacity() : 4
a
b
c
d
///////////////////////////////////
a copy constructor
0073A578 v.capacity() : 2
a copy constructor
b copy constructor
a copy constructor
b copy constructor
c copy constructor
0073E970 v.capacity() : 4
a
b
c
d
不知道为什么拷贝构造函数调用不稳定
所以。
v.push_back(A("a"));
v.push_back(A("b"));
v.shrink_to_fit();
cout << &v[0] << " v.capacity() : " << v.capacity() << endl;
我对这部分的预期输出是:
a copy constructor
b copy constructor
009A6CA8 v.capacity() : 2
但输出不同
a copy constructor
b copy constructor
a copy constructor
009A6CA8 v.capacity() : 2
我不知道为什么我在这部分又打了一次'a'。
其他人也是如此。有些是重复的,有些不是。
我想看看复制构造函数和移动调用之间的区别。代码有错吗?
如果你想研究移动构造函数,你必须提供一个。具有用户提供的复制构造函数(如您的)的 class 没有移动构造函数,因此不会被移动。因此,它将被复制到原本可以移动的地方。
在输出中
a copy constructor
b copy constructor
a copy constructor
009A6CA8 v.capacity() : 2
第一个a copy constructor
来自A(a)
被复制到向量中。
第二个 a copy constructor
是因为矢量 resizing。当您压入第二个元素时,向量将调整大小,这可能包括分配新内存并将旧元素复制到新内存中。
尝试在第一个 push_back
之前打印 capacity
并在第一个 和第二个 push_back
之间打印 (没有任何 shrink_to_fit
).您会看到容量从 0
到 1
再到 2
。容量的每次增加都是一个新的分配,它将复制所有现有元素(但是从 0
到 1
向量中没有元素,因此不会复制任何内容)。