没有默认构造函数和迭代器的对象向量

Vector of objects without a default constructor and iterator

我正在学习使用 C++ 向量,但我不太理解以下程序的输出:

#include <iostream>
#include <vector>

using namespace std;

class Custom {
public:
    int v;

    Custom() = delete;

    explicit Custom(int v) : v{v} {};

    Custom(const Custom &) : v{4} {

    }

    friend ostream &operator<<(ostream &os, const Custom &th) {
        os << "V is " << th.v << endl;
        return os;
    }
};


int main(int argc, char *argv[]) {
    vector<Custom> c(2, Custom(3));
    c[0].v = 5;

    for (auto i: c) {
        cout << i << endl;
    }

}

我预计它会产生输出

V is 5
V is 4

但它却产生了

V is 4

V is 4

我是不是遗漏了什么明显的东西?谢谢

这个基于范围的循环正在复制:

for (auto i: c) {
    cout << i << endl;
}

并且复制构造函数将 v 初始化为 4(并且不进行复制):

Custom(const Custom &) : v{4} {

}

您可以实现适当的复制构造函数或在循环中使用引用来获得所需的输出:

for (const auto& i: c) {
    cout << i << endl;
}

我建议两者都做,因为这个复制构造函数没有以任何方式进行复制。编译器生成的复制构造函数应该没问题:

Custom(const Custom &) = default;

PS:Custom 删除了默认构造函数这一事实与发布的代码无关。代码中没有任何地方默认构造了 Custom 。您的代码中也没有迭代器。在基于范围的循环中 i 是向量中元素的 copy/reference,它不是迭代器。

当你写道:

for (auto i: c) //this uses copy constructor to copy initialize each element one by one from the vector
{

}

在上面的代码片段中,向量的每个单独元素都用于 复制初始化 一个名为 i 的临时对象,同时遍历向量。并且由于您在复制构造函数的 构造函数初始值设定项列表 中有 v{4},因此您会得到上述输出。

要解决此问题,您应该将:auto i: c 替换为 auto &i: cconst auto &i: c,如下所示:

for (const auto &i: c) 
{
   cout << i << endl;
}

现在矢量的元素没有被复制i。相反,它们是对对象本身的引用,因此您将获得预期的输出。