2009-08-09 5 views
2

Ich versuche, meinen eigenen Std :: string-Wrapper zu erstellen, um seine Funktionalität zu erweitern. Aber ich habe ein Problem bei der Deklaration der < < Operator. Hier ist mein Code so weit:Rückgabewert für eine << - Operatorfunktion einer benutzerdefinierten Zeichenfolgenklasse in C++

meine benutzerdefinierten String-Klasse:

class MyCustomString : private std::string 
{ 
public: 
    std::string data; 
    MyCustomString() { data.assign(""); } 
    MyCustomString(char *value) { data.assign(value); } 
    void Assign(char *value) { data.assign(value); } 
    // ...other useful functions 
    std::string & operator << (const MyCustomString &src) { return this->data; } 
};

das Hauptprogramm:

int main() 
{ 
    MyCustomString mystring("Hello"); 
    std::cout << mystring; // error C2243: 'type cast' : conversion from 'MyCustomString *' to 'const std::basic_string<_Elem,_Traits,_Ax> &' exists, but is inaccessible 

    return 0; 
}

I cout die Klasse als std :: string behandeln wollte, so dass Ich brauche nichts zu tun wie:

std::cout << mystring.data;

Jede Art von Hilfe wäre willkommen!

Danke.

Nur fyi: meine IDE ist Microsoft Visual C++ 2008 Express Edition.

+0

Ich bin Hinzufügen zu den anderen Antworten hier, der Grund, warum Sie eine freistehende (globale Funktion) brauchen, ist, weil der Typ des ersten Arguments ein 'std :: string 'oder ein beliebiger Typ sein muss, den Sie vor dem Operator' << 'haben wollen . – Skurmedel

+0

...Das ist die einzige Möglichkeit, einen solchen Operator bereitzustellen, ohne die tatsächliche Klasse std :: string zu ändern. – Skurmedel

Antwort

1

Erstens scheint ein Problem mit der Definition von MyCustomString zu bestehen. Er erbt privat von std::string und enthält eine Instanz von std::string selbst. Ich würde das eine oder andere entfernen.

Angenommen, Sie einen neuen String-Klasse implementieren und Sie ausgeben möchten in der Lage sein es std::cout verwenden, müssen Sie einen Cast-Operator benötigen, um die String-Daten zurück, die std::cout erwartet:

operator const char *() 
{ 
    return this->data.c_str(); 
} 
4

Wenn Sie schauen, wie alle Stream-Betreiber erklärt werden sie von der Form sind:

ostream& operator<<(ostream& out, const someType& val); 

im Wesentlichen die Ausgabeoperation tatsächlich tun Sie überladene Funktion wollen und dann den neuen aktualisierten Strom Operator zurück. Was würde ich vorschlagen, Sie folgendermaßen vorgehen ist zu beachten, dass dies eine globale Funktion, kein Mitglied der Klasse:

ostream& operator<< (ostream& out, const MyCustomString& str) 
{ 
    return out << str.data; 
} 

Beachten Sie, dass, wenn Ihre ‚Daten‘ Objekt privat ist, die grundlegende OOP sagt es wahrscheinlich sollte, Sie können den obigen Operator intern als "Freund" -Funktion deklarieren. Dadurch kann es auf die private Datenvariable zugreifen.

+0

Guter Punkt. Oder er kann eine Accessor-Funktion verwenden. – jkeys

1

So überladen Sie den < < Operator nicht. Sie müssen einen Verweis auf einen Ostream eingeben und einen zurückgeben (so können Sie mehrere < < wie std::cout << lol << lol2 stapeln).

ostream& operator << (ostream& os, const MyCustomString& s); 

Dann tun nur dies:

ostream& operator << (ostream& os, const MyCustomString& s) 
{ 
    return os << s.data; 
} 
2

Sie benötigen eine freistehende Funktion (Freund der Klasse, wenn Sie Ihre machen data privat wie Sie wahrscheinlich sollte!)

inline std::ostream & operator<<(std::ostream &o, const MyCustomString&& d) 
{ 
    return o << d.data; 
} 
Verwandte Themen