下面的虚拟程序模仿我正在排除故障的另一个程序的行为。为什么方法范围结束后矢量内容发生了变化?
#include <iostream>
#include <vector>
class A
{
public:
std::vector<int> data;
void DoTheThing()
{
while (data.size() < 10) {
data.push_back(1);
}
}
};
class B
{
public:
std::vector<A> objs;
B()
{
A one, two, three;
objs.push_back(one);
objs.push_back(two);
objs.push_back(three);
}
void DoTheThing()
{
for (auto obj: objs) {
obj.DoTheThing();
std::cout << "DEBUG length during=" << obj.data.size() << std::endl;
}
}
};
int main()
{
B b;
b.DoTheThing();
for (auto obj : b.objs) {
std::cout << "DEBUG length after=" << obj.data.size() << std::endl;
}
}
予编译和作为运行:
$ g++ -Wall --std=c++11 -o test test.cpp
$ ./test
DEBUG length during=10
DEBUG length during=10
DEBUG length during=10
DEBUG length after=0
DEBUG length after=0
DEBUG length after=0
$
出于某种原因,A
物体在b
的objs
向量状态在b.DoTheThing()
呼叫和随后的打印语句之间改变。我的问题是发生了什么? A
对象data
矢量以某种方式超出范围并被删除,或者可能是整个A
对象?这似乎是一个范围问题 - 可能甚至是一个简单的问题 - 但它已经足够长,因为我用C++编程,我不确定。在其他方法中调用b.DoTheThing()
后,如何使data
向量的内容保持不变?
复制构造函数'explicit'可能会导致其他问题。最好只学习语言以了解制作副本的位置,并在需要时避开它。 –
@JonathanWakely,其中一个已知问题是RVO的事情。在某些情况下可以解决这个问题,我已经在答案中更新了。是的,“显性”有其自身的局限性,但我认为它们值得。几周前我已经遇到过这种情况,调试真的很困难。我们也可以在它下面有一个'#ifdef /#endif'并创建一个'#define conditional_explicit explicit'。这对最终检查任何这样的副本并恢复正常很有用。 – iammilind