C++ 我不知道';我不知道为什么复制构造函数';s调用在c+中不稳定+;

C++ 我不知道';我不知道为什么复制构造函数';s调用在c+中不稳定+;,c++,constructor,copy,move,C++,Constructor,Copy,Move,我学习理解Move的概念,并编写代码来查看复制构造函数调用的差异 但令人尴尬的是复制构造函数的调用不稳定。 我不明白为什么它是这样印刷的 下面是一个简单的示例代码 #include <iostream> #include <vector> #include <string> using namespace std; class A { private: string s; public: A(string s) : s(s) {}

我学习理解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
009A6CA8 v.capacity() : 2
我不知道为什么在这部分我又叫了一次“a”

其他人也是如此。有些是重复的,有些不是


我想看看复制构造函数和移动调用之间的区别。代码错了吗?

如果要研究移动构造函数,必须提供一个。具有用户提供的复制构造函数的类(如您的类)没有移动构造函数,因此不会移动。因此,它将被复制到可以移动的地方。

在输出中

a copy constructor
b copy constructor
a copy constructor
009A6CA8 v.capacity() : 2
a(a)
被复制到向量中时,第一个
复制构造函数
就出现了

第二个
是复制构造函数
,这是因为向量的大小调整。当您按下第二个元素时,向量将被调整大小,这可能包括分配新内存和将旧元素复制到新内存中


尝试在第一次
后推
之前以及在第一次和第二次
后推
之间打印
容量
(无任何
收缩以适应
)。您将看到容量从
0
1
2
。容量的每次增加都是一个新的分配,它将复制所有现有元素(但从
0
1
向量中没有元素,因此不会复制任何内容)。

对于所示的示例,您不需要复制构造函数。如果没有复制构造函数,编译器将自动为您生成一个,这样做是正确的。还请注意,复制构造可能会被省略(即编译器将在不调用复制构造函数的情况下执行就地构造)。您能否尝试详细说明您认为显示的输出有什么奇怪或“不稳定”的地方?“你能指出一些细节吗?”某个程序员杜德解释道。我希望能见到你。
emplace\u back()
如果没有移动构造函数也会复制吗?
emplace\u back
将在适当的位置构建。但如果需要重新分配以提供后面的空间,则重新分配将首先移动或复制现有对象。如果可能,调整大小将移动元素。但该类缺少移动构造函数。
a copy constructor
b copy constructor
009A6CA8 v.capacity() : 2
a copy constructor
b copy constructor
a copy constructor
009A6CA8 v.capacity() : 2
a copy constructor
b copy constructor
a copy constructor
009A6CA8 v.capacity() : 2