Object wie in Java?



  • blacksun schrieb:

    Ich möchte eine Liste als Speichermanager schreiben und dafür brauche ich natürlich eine allgemeine Ablage für die zu speichernden Objeckte.

    Wenn ein Speichermanager im Sinn von Arbeitsspeicher gemeint ist, dann void*.



  • @fricky:
    Dass es in Java breit akzeptierte Praxis ist wie wild rumzucasten liegt eigentlich nur daran dass es so lange Zeit in Java keine Generics gab. Und nicht daran dass es "in Java kein Problem" wäre. Das Problem gibt es dort genauso.



  • fricky schrieb:

    ...in Java ist das alles aber kein problem....

    Das würde ich nicht so sagen. IMHO (und nach meiner bescheidenen Java-Erfahrung) ist das "Java-Konzept"

    • die Typinformation erstmal zu "vergessen" (beim Eintragen in den Container) und
    • dann den "Empfänger" raten zu lassen,

    durchaus Auslöser für unschönen Code und eine Menge Probleme.

    imho macht C++ es da besser und ich finde es ein wenig seltsam, wenn Leute unglaublich viel Energie und "Frickelei" (nicht persönlich gemeint 😉 ) dareinstecken, diese Designsicherheit zu umgehen....

    Aber es ist vermutlich der Versuch FORTRAN .... ähhh Java in C++ zu programmieren. 😉

    Gruß,

    Simon2.

    P.S.: Aber es stimmt natürlich, wir haben es hier mit unterschiedlichen Philosophien zu tun ... aber gerade deswegen rate ich dazu, in C++ auch die C++-Philosophie zu verwenden - so wie ich auch beim Javaprogrammieren die Javaphilosophie "überstreife" ... nicht, weil ich sie für die bessere hielte, sondern in dem Fall die "passendere".



  • im gegensatz zu c++ sind casts in java völlig ungefährlich. alles was schiefgehen könnte ist, dass der cast nicht erlaubt ist und eine exception fliegt. so gruselige sachen wie in c++ können mit casts gar nicht passieren. daher ist die akzeptanz in java wesentlich höher. und bevor es die c++ templates gab, existierten auch nur entweder handgeschnitzte container oder gruseliger code, der mit void* pointern rumhantiert hat.



  • Was "Laufzeitfehler" angeht, stimme ich Dir zu, aber "designtechnisch" sind die Probleme schon da.

    thordk schrieb:

    ...bevor es die c++ templates gab, existierten auch nur entweder handgeschnitzte container oder gruseliger code, der mit void* pointern rumhantiert hat.

    Definitv.
    Allerdings gibt's bei C++ ja templates und die Container schon quasi "von Anfang an".
    (Deswegen bekomme ich auch immer die Krise, dass bei uns in der Firma bei bestimmten Bereichen nur C (und kein C++) eingesetzt werden kann/darf/soll/.... was müssen wir uns da mit häßlichem und unsicheren selbstgeschriebenen Zeug rumschlagen, wo ein C++er einfach ein std::<xyz> hingeschrieben hätte 🙄 🙄 )

    Gruß,

    Simon2.



  • thordk schrieb:

    im gegensatz zu c++ sind casts in java völlig ungefährlich.

    dynamic_cast verhaelt sich aehnlich wie java casts.

    und btw, es gibt einen grund warum java generics eingefuehrt hat: weil sie eben viel sicherer sind als lauter void* aeh, ich meine Object referenzen hin und her zu schieben.

    klar fliegt "nur" eine exception - aber eine exception im falschen moment bedeutet dennoch, dass man sich davon nicht so leicht erholen kann (vorallem wenn man damit nicht gerechnet hat).



  • Simon2 schrieb:

    fricky schrieb:

    ...in Java ist das alles aber kein problem....

    Das würde ich nicht so sagen. IMHO (und nach meiner bescheidenen Java-Erfahrung) ist das "Java-Konzept"

    • die Typinformation erstmal zu "vergessen" (beim Eintragen in den Container) und
    • dann den "Empfänger" raten zu lassen,

    durchaus Auslöser für unschönen Code und eine Menge Probleme.

    ne, Java vergisst nicht, welches object das ist. in Java gibts 'instanceof' um zur laufzeit zu testen, wohin man upcasten darf. für compilerchecks diesbezüglich gibts 'generics'. C++ hat ja sowas ähnliches, RTTI und 'typeid', aber das mag irgendwie keiner verwenden. C++-coder machen lieber alles statisch (mit templates) und hassen laufzeit-polymorphismus.
    🙂



  • würde man den ein objekt serialisieren? so etwa?

    class DATA{
    
    int a,b,c;
    float d,e,f;
    
    DATA(){}
    ~DATA(){}
    void funk(..){}
    .
    .
    .
    };
    
    DATA obj;
    
    ofstream out("test", ios::out | ios::binary); 
    out.write((char*)&obj, sizeof(DATA);
    

    glaube nich das das geHT!?!?!?!



  • fricky schrieb:

    ...
    ne, Java vergisst nicht, welches object das ist....

    Das habe ich auch nicht behauptet.
    Es ist nur so, dass der "Empfänger" raten muss, was für ein Objekt denn da nun so als nächstes in der Hand hat und dann entscheiden (da gibt's auch kein Standardvorgehen), ob er unpassende Objekte einfach ignorieren, mit einem Fehler abbrechen oder versuchen soll, auf irgendetwas anderes zu casten.
    Blöderweise hat man keine Möglichkeit mehr, die Fehlerursache selbst (falsches Objekt übergeben) noch zu korrigieren.
    Ergo: Der Programmierer vergisst, welchen Typ das Objekt hat.
    (wenn "Java" das vergessen würde, hätte der Programmierer ja nicht einmal mehr die Chance, halbwegs sicher zu raten)
    ... und das Vorgehen finde ich nach wie vor für Quatsch. Aber es ist eben zu Zeiten der Javaentstehung nicht anders möglich gewesen.
    Im Prinzip ist das nicht anders als zu void*-Listen zu C-Zeiten (allerdings garniert mit einer Runtime, die einem die "Typflag"-Verwaltung abnimmt).

    fricky schrieb:

    ...RTTI und 'typeid', aber das mag irgendwie keiner verwenden. C++-coder machen lieber alles statisch (mit templates) ...

    zurecht, weil C++-Programmierer Programmierfehler halt lieber zur Compile- als zur Laufzeit bekommen ... weil sie seltsamerweise davon ausgehen, dass der Programmierer damit mehr anfangen kann als der Anwender.

    fricky schrieb:

    ...hassen laufzeit-polymorphismus.
    :)...

    Im Gegenteil. Sie lieben Laufzeitpolymorphie (schau Dich nur mal hier im Forum an, wie oft unter dem Schlagwort "virtual" genau dazu geraten wird) ...
    was sie nicht lieben, ist Problempropagation vom Entwickler zum Anwender. 😉

    Gruß,

    Simon2.



  • Serialisieren schrieb:

    würde man den ein objekt serialisieren? ...

    Auch hier nochmal: Da es in C++ kein einheitliches (compiler-/plattformübergreifendes) Objektlayout gibt, rate ich dringend von einem "Binärspeichern" ab. Das mag immer erstmal die erste Idee sein, sie ist aber bestimmt nicht die Beste.

    Mein Vorschlag: operator<<() und operator>>() überladen und das Teil so Wegschreiben und Einlesen, wie man es auch über die Konsole tut.
    (Damit sind zwar die Files auch noch nicht Codepage-unabhängig, aber ansonsten schon weitestgehend compiler-/plattformunabhängig und für Codepage-Konvertierung (die sehr viel seltener sind) gibt es einfach und allgemeine Tools)

    Hier übrigens mal eine (wie ich finde) recht gute Auseinandersetzung mit dem Thema...

    Gruß,

    Simon2.



  • Simon2 schrieb:

    fricky schrieb:

    ...
    ne, Java vergisst nicht, welches object das ist....

    Das habe ich auch nicht behauptet.
    Es ist nur so, dass der "Empfänger" raten muss, was für ein Objekt denn da nun so als nächstes in der Hand hat und dann entscheiden

    er muss nix raten. er kann das objekt fragen: "wer bist du?"

    Simon2 schrieb:

    fricky schrieb:

    ...RTTI und 'typeid', aber das mag irgendwie keiner verwenden. C++-coder machen lieber alles statisch (mit templates) ...

    zurecht, weil C++-Programmierer Programmierfehler halt lieber zur Compile- als zur Laufzeit bekommen ... weil sie seltsamerweise davon ausgehen, dass der Programmierer damit mehr anfangen kann als der Anwender.

    das ist aber eine sehr seltsame erklärung. die anderen sagen immer, RTTI u.ä. soll man nicht nehmen, weil es das programm ausbremsen würde.
    🙂



  • fricky schrieb:

    ...
    er muss nix raten. er kann das objekt fragen: "wer bist du?"...

    Und dann ?
    Was macht denn ein Programm, das Autoteile verwaltet, wenn das Objekt sich als "Windelwechsler-Objekt" zurückmeldet ?
    Erstmal per Reflection die Methoden abfragen und dann mit Windel wechseln weitermachen ?

    Simon2 schrieb:

    ...das ist aber eine sehr seltsame erklärung. die anderen sagen immer, RTTI u.ä. soll man nicht nehmen, weil es das programm ausbremsen würde.
    🙂

    Das stimmt natürlich auch ... eine Technik kann ja mehr als einen Nachteil haben. Wie man das gewichtet, bleibt jedem selbst überlassen.

    P.S.: Ich glaub übrigens nicht, dass RTTI in Java weniger performancefressend ist ... aber da hat man eben nichts Anderes.

    Gruß,

    Simon2.



  • fricky schrieb:

    er muss nix raten. er kann das objekt fragen: "wer bist du?"

    Das kann man ja, wie du schon angedeutet hast, mit C++ auch machen.

    std::vector<boost::any> myObjects;
    //...
    for (size_t i = 0; i < myObjects.size(); ++i)
    {
        const std::type_info &info = myObjects[i].type();//Wer bist du?
        //...
    }
    


  • Weiß nicht, ob es hier schon genannt wurde. Aber Boosts Serialization Library könnte vielleicht helfen? Es macht die Sache zwar nicht so "einfach" wie in Java, aber es kann einen zumindest als C++ler unterstützen, sich ein mächtigeres Serialization-System zu bauen:
    http://www.boost.org/doc/libs/1_35_0/libs/serialization/doc/index.html

    Aber wie Simon2 auch schon sagte, man kann ja erstmal die Stream-Operatoren überladen und von Hand was basteln. Wenn man nur wenige Klassen hat, die serialisiert werden können sollen, ist das ja schnell gemacht.



  • BarnieGeroellheimer schrieb:

    ...
    Aber wie Simon2 auch schon sagte, man kann ja erstmal die Stream-Operatoren überladen und von Hand was basteln. Wenn man nur wenige Klassen hat, die serialisiert werden können sollen, ist das ja schnell gemacht.

    Hmmm, muss ich das in Java nicht auch machen ? (also: serialize() implementieren)

    Gruß,

    Simon2.



  • Jain! Man muß nur implements Serializable in seine Klasse hauen (evtl. noch diese komische neue Serializable-ID) und dann funktioniert es automatisch. Also wirklich hacken muß man da nicht.



  • Simon2 schrieb:

    Hmmm, muss ich das in Java nicht auch machen ? (also: serialize() implementieren)

    Nicht wirklich. Serializables haben immer ne default implementierung die alles nicht transienten variablen rausschreibt.

    Man kann Serialisierung in Java aber auch mit Reflection einmal für alle Objekte die es jemals geben wird machen, siehe Hibernate.



  • Simon2 schrieb:

    fricky schrieb:

    ...
    er muss nix raten. er kann das objekt fragen: "wer bist du?"...

    Und dann ?
    Was macht denn ein Programm, das Autoteile verwaltet, wenn das Objekt sich als "Windelwechsler-Objekt" zurückmeldet ?
    Erstmal per Reflection die Methoden abfragen und dann mit Windel wechseln weitermachen ?

    sei doch nicht albern. was hat der windelwechsler zwischen den autoteilen verloren?

    Simon2 schrieb:

    P.S.: Ich glaub übrigens nicht, dass RTTI in Java weniger performancefressend ist ... aber da hat man eben nichts Anderes.

    jedenfalls ist es nicht so schlimm, dass einem davon abgeraten wird. Javaprogramme sind sehr vieles dynamischer als C++-codes, benutzen oft on-the-fly class loaders, beans, etc. das ist da alles ganz normal.
    🙂



  • fricky schrieb:

    ...sei doch nicht albern. was hat der windelwechsler zwischen den autoteilen verloren?...

    Ja, genau das ist ja die Frage, die man den Java-Container-Designern stellen muss.
    Da Du aber als "Rausnehmer" alles erwarten musst (außer primitive Typen, aber eben auch "WindelwechselObject"), muss Dein Programm auch damit klarkommen (und zwar jedes wieder neu). In C++ sichert mir mein vector<Autoteil*> in meiner Schnittstelle schon zu, dass ich auf jeden Fall eine Autoteil-Schnittstelle vorfinde....

    fricky schrieb:

    ...jedenfalls ist es nicht so schlimm, dass einem davon abgeraten wird. ...

    Naja, man hat halt keine Alternative. :p 😉

    Aber prinzipiell entspricht das eben der oben schon angesprochenen "Java-Philosophie", alles zur Laufzeit zu machen/entscheiden (wird dann "dynamisch" genannt) - hat seine Vor- und seine Nachteile.

    Gruß,

    Simon2.



  • Simon2 schrieb:

    fricky schrieb:

    ...sei doch nicht albern. was hat der windelwechsler zwischen den autoteilen verloren?...

    Ja, genau das ist ja die Frage, die man den Java-Container-Designern stellen muss.
    Da Du aber als "Rausnehmer" alles erwarten musst (außer primitive Typen, aber eben auch "WindelwechselObject"), muss Dein Programm auch damit klarkommen (und zwar jedes wieder neu). In C++ sichert mir mein vector<Autoteil*> in meiner Schnittstelle schon zu, dass ich auf jeden Fall eine Autoteil-Schnittstelle vorfinde....

    Generics in Java sind dir bekannt?


Anmelden zum Antworten