Jeśli obiekty które próbujesz wypisac operatorem << to stringi to prawdopodobnie zapomniałes zaincludować:
#include <string>
Sama deklaracja stringa działa, bo "część" nagłówka string została zaincludowana przez nagłówek <iostream>. Jednak nie było tam przeładowania operatora <<, wiec kod się nie kompiluje mimo, że mogłeś używać samego typu.
String w środku mógłby wyglądać jakoś tak:
class UbogiString {
public:
UbogiString & operator=(const char *s) {
tab = s;
}
private:
const char * tab;
};
//bez tego kompilator nie wiedzialby co zrobić gdy zobaczy
//cout<<obiektTejKlasy
ostream& operator<<(ostream& out, const UbogiString& s) {
out << s;
return out;
}
int main()
{
UbogiString s;
s = "Polska dla polakow, ziemia dla ziemniakow";
cout << s << endl;
return 0;
}
Gdy nie zaincludowałeś <string> to brakowało Ci tej funkcji, która mówi kompilatorowi co ma zrobić gdy zobaczy cout<<obiektTwojejKlasy;
Co do samego przeciążania: zdefiniowałem co ma się stać gdy spróbuje przypisać const char* do obiektu klasy UbogiString i co ma się stać gdy spróbuje zrobić cout<<obiektKlasyUbogiString;.
Reszte poczytaj na necie, o przeciążaniu jest mnóstwo tutoriali w każdym języku i pozimie zaawansowania.