没有默认构造函数和迭代器的对象向量
我正在学习使用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这个基于范围的循环正在制作副本:
并且复制构造函数将
v
初始化为4
(并且不进行复制):您可以实现适当的复制构造函数或使用引用在循环中获得所需的输出:
我建议同时执行这两项操作,因为此复制构造函数无论如何都不会执行复制。编译器生成的复制构造函数应该没问题:
PS:
Custom
具有已删除的默认构造函数这一事实与发布的代码并不真正相关。代码中没有任何地方默认构造Custom
。您的代码中也没有迭代器。在基于范围的循环中,i
是向量中元素的副本/引用,它不是迭代器。This range based loop is making copies:
And the copy constructor initializes
v
to4
(and does not make a copy):You can either implement a proper copy constructor or use references in the loop to get the desired output:
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:
PS: The fact that
Custom
has a deleted default constructor is not really relevant for the posted code. Nowhere in the code aCustom
is default constructed. Also there is no iterator in your code. In the range based loopi
is a copy/reference of the elements in the vector, it is not an iterator.当您编写时:
在上面的代码片段中,向量的每个单独元素都用于在迭代向量时复制初始化名为
i
的临时对象。由于复制构造函数的构造函数初始值设定项列表中有v{4}
,因此您将获得上述输出。要解决此问题,您应该将
auto i: c
替换为auto &i: c
或const auto &i: c
,如下所示:现在向量的元素未复制到
i
中。相反,它们是对对象本身的引用,因此您将获得预期的输出。When you wrote:
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 thev{4}
in the constructor initializer list of the copy constructor you get the mentioned output.To solve this you should replace:
auto i: c
withauto &i: c
orconst auto &i: c
as shown below: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.