Czemu funkcja:

std::istream & operator>>(std::istream & is, const complex & c)
{
	std::cout << "skladowa rzeczywista: ";
	is >> c.real;
	std::cout << "skladowa urojona: ";
	is >> c.imag;
	return is;
}

się zapętla?

P.S. Już wiem dlaczego, bo konstruktor daje możliwość konwersji double na complex. Dodatkowo trzeba wyrzucić słowo const z parametru complex.