迭代器成员行为
我期待下面的第二个断言能够通过。我请求你的帮助。
编辑:当我到处都是 poss 而不是某些地方的 poss_a 时,它不起作用。
#include <vector>
#include <cassert>
class Sampler
{
public:
std::vector<int*> poss;
std::vector<int*>::const_iterator poss_it;
Sampler(std::vector<int*> poss_a) : poss(poss_a), poss_it(poss.begin())
{
assert( (poss[0]) == (*poss_it) ); //passes
}
};
int main()
{
int someInt;
std::vector<int*> poss_a(1, &someInt);
Sampler sampler(poss_a);
assert( ((sampler.poss)[0]) == (*(sampler.poss_it)) ); //passes now
return 0;
}
I was expecting the second assert in the following to pass. I'm asking for your help.
Edit: It didn't work when I had poss everywhere instead of poss_a in some places.
#include <vector>
#include <cassert>
class Sampler
{
public:
std::vector<int*> poss;
std::vector<int*>::const_iterator poss_it;
Sampler(std::vector<int*> poss_a) : poss(poss_a), poss_it(poss.begin())
{
assert( (poss[0]) == (*poss_it) ); //passes
}
};
int main()
{
int someInt;
std::vector<int*> poss_a(1, &someInt);
Sampler sampler(poss_a);
assert( ((sampler.poss)[0]) == (*(sampler.poss_it)) ); //passes now
return 0;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
初始化列表中的 poss_it(poss.begin()) 行从作为构造函数输入的 poss 中提取一个迭代器,而不是作为类的字段的迭代器。
这是一个范围问题。当您在构造函数中时,这很好,因为您的迭代器是指向函数输入的指针。然而,当您离开构造函数时,它指向内存中的同一位置,但现在您不知道该位置有什么。
您应该更改构造函数中输入变量的名称。您想要一个能够执行此操作的:
而您当前正在执行的操作是:
The
poss_it(poss.begin())
line in your initializer list is pulling an iterator from the poss that is the input to the constructor, not the one that is a field of the class.This is a scope issue. When you're in the constructor, it's fine, because your iterator is a pointer to the input to the function. When you leave the constructor however, it's pointing to the same spot in memory but now you have no idea what's at that location.
You should change the name of the input variable in the constructor. You want one that does this:
Whereas what your current one is doing is this:
可能会对覆盖实例变量的局部变量感到困惑,请尝试
Probably getting confused over the local variables overriding the instance variables, try
您本质上是在调用未定义的行为,因为
sampler.poss_it
是一个std::vector
对象的迭代器,该对象在第二个assert< 之前被破坏。 /code> 已执行。
问题出在线上:
poss(poss)
的第一个poss
引用了Sampler
对象的poss
成员,poss(poss)
的第二个poss
引用了poss
参数,poss
的>poss_it(poss.begin()) 再次引用poss
参数(不是poss
成员)。 poss 参数在构造函数末尾超出范围,因此 poss 参数被破坏,这意味着 poss_it 迭代器不再有效的。为了避免此类问题,C++ 程序员几乎总是避免隐藏变量。另外,复制构造函数可能应该采用 const 引用(以避免潜在大对象的值传递):
You are essentially invoking undefined behavior because
sampler.poss_it
is an iterator into astd::vector<int*>
object that was destructed before the secondassert
was executed.The problem was on the line:
where the first
poss
ofposs(poss)
refers to theSampler
object'sposs
member, the secondposs
ofposs(poss)
refers to theposs
parameter, and theposs
ofposs_it(poss.begin())
refers again to theposs
parameter (not theposs
member). Theposs
parameter goes out of scope at the end of the constructor, so theposs
parameter is destructed, meaning that theposs_it
iterator is no longer valid.To avoid this type of problem, C++ programmers almost always avoid shadowing variables. Also, a copy constructor should probably take a const-reference (to avoid pass-by-value for potentially large objects):