Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Hilfe mit cast operator

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ]
000
02.11.2016, 06:37 Uhr
Joe1903



Hallo.Ich bin ein C++-Neuling und habe ein Problem bzw. eine Frage,bei der ich nicht weiterkomme.
Und soll ich ein Beispielprogramm einer Klasse schreiben,die wesentliche Data Members via cast operator (operator const char *(void) const) als C Style String liefert.Dabei soll der cast Operator das Objekt selbst nicht ändert.

Könnte jemand vielleicht ein Beispiel mit irgendeinem Data Member schreiben?

Vielen Dank im Voraus.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
02.11.2016, 08:44 Uhr
ao

(Operator)


O weh. Ich fürchte, das wird ne üble Kacke. Ein Umwandlungsoperator auf C-Style-String - wenn man das mit sauberem Speichermanagement hinkriegen will, muss man sich an irgendeiner Stelle ziemlich verrenken. Und eigentlich gibts in C++ für solche Dinge eine String-Klasse, so dass man auf const char * gut verzichten könnte. Blöde Aufgabe, unnötig kompliziert und verwirrend.

Aber wenns dem Herrn Dozenten oder der Frau Dozentin so gefällt ... Was hast du denn schon geschrieben und vor allem: Wie sieht die Klasse aus? Was sind das für "wesentliche Data Members"?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
02.11.2016, 10:13 Uhr
~somebody
Gast


Das ist ganz einfach.

Du sollst die Member serialisieren und bestenfalls in ein std::vector<char> einfügen.

Kleines Beispiel:


Code:
std::copy((char*)&inst.x, (char*)&inst.x + sizeof(inst.x), std::back_inserter(char_vec));
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
02.11.2016, 10:41 Uhr
ao

(Operator)


Dabei entsteht aber kein C-Style-String (d.h. null-terminierter druckbarer Text), sondern einfach eine binäre Kopie der Daten. Ich bezweifle, dass das der Aufgabe entspricht, aber dass kann Joe ja klären, indem er die Aufgabe hier zitiert.

Und das Problem "wie kriege ich den String zerstörungs- und speicherleckfrei aus dem Operator heraus" bleibt bestehen.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
02.11.2016, 11:02 Uhr
Joe1903



Die Anwendung soll so aussehen: Trace der Data Members einer Instanz via

class X
{
...
operator const char *(void) const
throw();
...
};

Xx;
const char*dataAsString = x;
printf("x=%s\n",dataAsString); )



Zitat von ao:
O weh. Ich fürchte, das wird ne üble Kacke. Ein Umwandlungsoperator auf C-Style-String - wenn man das mit sauberem Speichermanagement hinkriegen will, muss man sich an irgendeiner Stelle ziemlich verrenken. Und eigentlich gibts in C++ für solche Dinge eine String-Klasse, so dass man auf const char * gut verzichten könnte. Blöde Aufgabe, unnötig kompliziert und verwirrend.

Aber wenns dem Herrn Dozenten oder der Frau Dozentin so gefällt ... Was hast du denn schon geschrieben und vor allem: Wie sieht die Klasse aus? Was sind das für "wesentliche Data Members"?


(edit ao: quote-Tag repariert)

Dieser Post wurde am 02.11.2016 um 12:51 Uhr von ao editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
02.11.2016, 11:11 Uhr
~somebody
Gast


Dann nimm halt statt einem vector<char> einfach nen String, dann nimmst du std::copy() serialisierst alles, und gibst s.c_str() zurück. Der String sollte dabei Member der Klasse sein, sonst zeigt der Pointer irgendwo hin, wo mal was war, aber nix mehr is.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
02.11.2016, 12:36 Uhr
ao

(Operator)



Zitat von ~somebody:
Der String sollte dabei Member der Klasse sein, sonst zeigt der Pointer irgendwo hin, wo mal was war, aber nix mehr is.

"sonst zeigt der Pointer ...": Korrekter Einwand, genau das meinte ich mit "üble Kacke". @Joe: Verstehst du, was damit gemeint ist?

"Der String sollte Member der Klasse sein": Das ist unvereinbar mit "operator const char *(void) const": Der Operator darf das Objekt nicht verändern. Der mutable-Trick ist damit vermutlich auch ausgeschlossen. Außerdem ist der Operator dann nicht mehr reentrant, worauf zumindest hingewiesen werden muss.

Wie mans auch dreht und wendet, es läuft immer wieder drauf hinaus, dass eine Umwandlung in const char* Mist ist und dass eine Umwandlung in ein selbstverwaltetes std::string-Objekt wesentlich eleganter wäre.

So bleibt wohl nur, das aus Plain-old-C überlieferte "strdup-Paradigma" wiederzubeleben: Der Operator legt per new[] ein char-Array an, füllt es und reicht es dem Aufrufer raus. Der Aufrufer muss es nach Gebrauch delete'n, sonst Speicherleck. Kann man so definieren und ist für einen simplen ToString-Operator ein ziemlicher Overkill, aber nur so geht es sicher. Wie gesagt, blöde Aufgabe.

Dieser Post wurde am 02.11.2016 um 12:53 Uhr von ao editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
02.11.2016, 13:24 Uhr
~somebody
Gast


Du kannst auch einen thread lokalen statischen Buffer in der Methode machen, den du bei jedem Aufruf wieder erstmal leerst und darauf dann rumoperierst.

Da gibts viele Möglichkeiten das zu machen.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
02.11.2016, 13:29 Uhr
Joe1903



Könnt ihr mir vielleicht ein Beispiel geben?Mit der Klasse die ich oben angegeben habe.
Mit irgendeinem Data Member..

Dieser Post wurde am 02.11.2016 um 13:49 Uhr von Joe1903 editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
02.11.2016, 13:57 Uhr
ao

(Operator)


Ja, kann ich machen. Ich mach jetzt einfach mal "C mit Klassen":

C++:
#include <stdio.h>

class X
{
    int n;                //    irgendein Member
    
public:

    X (int n_) : n (n_) {}
    operator char * (void) const;
};

X::operator char * () const
{
    char text [16];        //    Ausgabepuffer
    sprintf (text, "%d", n);
    return text;
}

int main ()
{
    X x(5);
    const char*dataAsString = x;
    printf("x=%s\n",dataAsString);
    return 0;
}



Das ist der "naive" Ansatz: Im Operator char* wird ein lokales Stück Speicher angelegt, mit dem Text gefüllt (sprintf) und zurückgegeben. Die Ausgabe in main liefert auf meinem Rechner (ubuntu) nicht das erwartete "x=5", sondern "x=(null)".
Grund dafür ist, dass das Array text lokal in der Operator-Funktion deklariert ist, d.h. es existiert nur, solange das Programm innerhalb der Funktion ist. Nach Verlassen der Funktion (also nach "return text;") wird der Speicher ans System zurückgegeben und was dort gespeichert ist, ist nicht mehr gültig. Dass die Main-Funktion trotzdem drauf zugreift und es dem printf zur Ausgabe übergibt, ist daher illegal und kann zufällig funktionieren, muss aber nicht.

Weiter im nächsten Beitrag.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ]     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: