c++ - 我不知道为什么c++中复制构造函数的调用不稳定

标签 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) {}

    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”。

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

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

最佳答案

在输出中

a copy constructor
b copy constructor
a copy constructor
009A6CA8 v.capacity() : 2

第一个复制构造函数来自于将A(a)复制到 vector 中。

第二个复制构造函数是因为 vector 调整大小。当您推送第二个元素时, vector 将被调整大小,其中可能包括分配新内存并将旧元素复制到新内存中。

尝试打印第一个 push_back 之前的容量以及第一个和第二个 push_back之间(不带任何shrink_to_fit)。您将看到容量从 0 变为 1 再到 2。每次容量增加都是一次新的分配,它将复制所有现有元素(但从 01 vector 中没有元素,因此不会复制任何内容)。

关于c++ - 我不知道为什么c++中复制构造函数的调用不稳定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59369640/

相关文章:

mongodb - 如何将 mongodb 数据库转移到另一台看不到第一个的机器上

php - 是否有将 PHP 数组复制到另一个数组的功能?

java - if、else if 和 else 语句? java

c++ - 如何在 POSTGRESQL 中捕获唯一约束错误

c++ - 有没有更简洁的方法来公开测试的实现细节?

c++ - QTableWidget - 将多行文本放在一行中

java - Scala 中如何计算默认构造函数参数?

c++ - 无法在类构造函数范围内初始化指针

docker - Docker-从其他工作目录到另一个工作目录的COPY文件不起作用

执行字符串分配时 C++ 程序崩溃