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

发布于 2025-01-13 04:55:08 字数 749 浏览 0 评论 0原文

我正在学习使用 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

我是否错过了一些明显的东西?谢谢。

I am learning to use C++ vectors, and I can't quite understand the output of the following program:

#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;
    }

}

I expected it to produce the output

V is 5
V is 4

But instead it produces

V is 4

V is 4

Am I missing something obvious? Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

猫性小仙女 2025-01-20 04:55:09

这个基于范围的循环正在制作副本:

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 是向量中元素的副本/引用,它不是迭代器。

This range based loop is making copies:

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

And the copy constructor initializes v to 4 (and does not make a copy):

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

}

You can either implement a proper copy constructor or use references in the loop to get the desired output:

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

I would suggest to do both, because this copy constructor is not doing a copy by any means. The compiler generated copy constructor should be fine:

Custom(const Custom &) = default;

PS: The fact that Custom has a deleted default constructor is not really relevant for the posted code. Nowhere in the code a Custom is default constructed. Also there is no iterator in your code. In the range based loop i is a copy/reference of the elements in the vector, it is not an iterator.

笛声青案梦长安 2025-01-20 04:55:09

当您编写时:

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中。相反,它们是对对象本身的引用,因此您将获得预期的输出。

When you wrote:

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

}

In the above snippet, each individual element of the vector is used to copy initiaize a temporary object named i while iterating through the vector. And since you have the v{4} in the constructor initializer list of the copy constructor you get the mentioned output.

To solve this you should replace: auto i: c with auto &i: c or const auto &i: c as shown below:

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

Now the elements of the vector are not copied into i. Instead they are references to the object themselves and so you'll get your expected output.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文