Operatoren müssen keine Member-Funktionen sein, sondern werden als globale Funktionen eingeführt, wobei ein Ausgabe-Operator als Argument eine Referenz auf einen ostream (bzw. basic_ostream) und eine Referenz auf die auszugebende Variable enthält und eine Referenz auf sich selbst zurückgibt. Eingabe-Operatoren werden analog dazu erstellt.
Beispiel:  std::ostream& operator << (std::ostream&, CString&);  std::istream& operator >> (std::istream&, std::stream&);
Für die Standard-Datentypen sind ostream bzw. istream bereits überladen. Wenn man eigene Operatoren definiert, versucht man zuerst, den ein-/auszugebenden Datentyp auf die Standard-Datentypen zurückzuführen.
Beispiel:  std::ostream& operator << (std::ostream& ostr, CString& cstr)  {   : return(ostr << (LPTCSTR) cstr);  }
Im Zweifelsfall kann man den Datentyp immer auf den Typ char zurückführen. Man kann sich auch der Funktionen istream::get(), istream::getline() und ostream::put() bedienen.
Bei der Deklaration von Operatoren für eigene Klassen muss man die Zugriffskontrolle beachten. Für die Ein-/Ausgabe von nicht-public Daten muss der Operator in der Klassen-Deklaration als friend eingeführt werden.
Mit den Operatoren  std::ostream& operator << (std::ostream&, CString&);  std::ostream& operator << (std::ostream&, std::string&);
  std::ostream& operator << (std::ostream& ostr, CString& cstr)  {   : return(ostr << (LPTCSTR) cstr);  }
  std::ostream& operator << (std::ostream& ostr, std::string& sstr)  {   : return(ostr << sstr.c_str());  }
ergibt sich das obige Beispiel zu:
  OG_constream text_fenster;
  int i = 10;  double d = 3.14156;  std::string sstr("STL String");  CString cstr("Microsoft CString");
  text_fenster << "i = " << i << std::endl;  text_fenster << "d = " << d << std::endl;  text_fenster << "STL String = " << sstr << std::endl;  text_fenster << "Microsoft CString = " << cstr << std::endl;