Wydaje mi się, że gdybyś użył getline zamiast cin, to wszystko by grało bez ignore.
1. Jeśli wpiszesz jakiś znak pętla wykonuje obrót.
2. Zostają czyszczone wewnętrzne flagi błędów.
3. Zostaje wypisany jakiś tekst.
4. Zostaje zignorowany biały znak - znak nowej linii.
Reasumując, jeśli nie napiszesz instrukcji
cin.ignore(1024, '\n');
, to wtedy do chyba bufora trafi wartość "jakiś tekst\n" i ten warunek (cin >> wybor) będzie zawsze na false (ponieważ do chyba bufora nie trafią dane, czyli tak naprawdę nic nie zostało wpisane w tymże buforze), co po zanegowaniu wykrzyknikiem z przodu zwróci zawsze true. Program, nie będzie miał jak poprosić o nową wartość, ponieważ chyba w buforze wisi poprzednia wartość, która nie została zatwierdzona do przeanalizowania przez program. Wpadamy więc w pętlę nieskończoną.
Dzieje się tak, dlatego że znak nowej linii zatwierdza daną wartość i jest porównywana chyba w buforze (chyba w strumieniu cin). Jeśli jednak nie zatwierdzisz danej wartości np. enter'em (znak nowej linii) - czyli nie zignorowałeś znaku nowej linii, to wtedy warunek pętli będzie zawsze spełniony, bo gdyby znak nowej linii zostałby zignorowany (zostałaby wtedy zatwierdzona wartość), to wtedy wartość w warunku pętli wynosiłaby false, co po zanegowaniu zwróci true - czyli pętla wykonałaby następny obrót, ale bez pętli nieskończonej, bo po tym true w ciele pętli while użytkownik zostałby poproszony o następną wartość do wpisania do chyba bufora.
W skrócie: (bez ignore) - user nie jest proszony o podanie nowej wartości do chyba bufora - powstaje pętla nieskończona;
(z ignore) - user jest proszony o podanie nowej wartości do chyba bufora - nie powstaje pętla nieskończona.
Dla testu można tak napisać:
bool xxx;
// ...
while(xxx = !(cin >> wybor)) {
cin.clear();
cout<<xxx;
//cin.ignore(1024, '\n'); // enable this line and disable later
}
// ...