次のダミープログラムは、トラブルシューティングしている別のプログラムの動作を模倣しています。メソッドスコープが終了した後にベクターコンテンツが変更されるのはなぜですか?
#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
$
をb
のobjs
ベクトルでA
オブジェクトの状態がb.DoTheThing()
コールとその後のprint文の間で変化しています。私の質問は何が起こっているのですか? A
オブジェクトdata
ベクターが何とかスコープから外れて削除されているか、またはおそらくA
オブジェクト全体ですか?それはスコープの問題のように思えます - おそらく単純なものでさえ - でも、私はC++でプログラミングして以来十分ではありません。他の方法でb.DoTheThing()
を呼び出した後に、data
ベクトルの内容を持続させるにはどうすればよいですか?
コピーコンストラクタ' explicit'を作ることは他の問題を引き起こす可能性があります。コピーを作成する場所を理解するための言語を学び、必要に応じてコピーを避けるだけです。 –
@JonathanWakely、そのような既知の問題の1つはRVOのことです。それは私が答えを更新した特定の状況で解決することができます。はい、「明示的」には独自の制限がありますが、私はそれが価値があると思います。私は数週間前にこのような状況にあったため、デバッグは本当に困難でした。 '#ifdef/#endif'sを作成し、' #define conditional_explicit explicit'をその下に作成することもできます。これは、そのようなコピーの最終的なチェックと通常の状態への復帰に役立ちます。 – iammilind