Eigene Klassenbibliothek



  • Hallo,

    nach langem Überlegen habe ich mich dazu durchgerungen, meine intern verwendete Klassenbibliothek doch zu veröffentlichen.

    Bevor ich mir aber die Mühe mache, die Quelldateien in einen Zustand zu bringen, daß sie veröffentlicht werden können, wollte ich fragen, ob überhaupt ein Interesse besteht.

    Deshalb gibt es hier schon mal eine Einführung zur Bibliothek:

    http://www.cresd.de/edv/ger/Products/gaklib.pdf

    Die wichtigsten (Basis)klassen sind:

    STRING
    Funktionen und Klassen zur Zeichenkettenbehandlung

    Container
    Speicherverwaltung

    XML_ELEMENT
    XML-Prozessoren.

    HTML_BASE
    HTML-Prozessoren

    Daneben gibt es Klassen für HTTP-Clients und -Server, XSLT-Transformation, Xschemavalidierung und CSS-Parser.

    Über eine Rückmeldung (auch konstruktive Kritik) würde ich mich freuen.

    mfg Martin



  • Highlights (mit kleinen Einfügungen):

    ARRAY<OBJ>
    Ein dynamisches Array.
    Beim Zugriff auf ein Index,
    der noch nicht exisitert,
    wird einfach das Array
    entsprechend erweitert.
    Wir wollen nämlich Logikfehler
    vertuschen, statt sie zu behandeln.

    SEARCHABLE_ARRAY<OBJ>
    Ein Array, das durchsucht
    werden kann. <algorithm>
    ist nämlich total doof.

    ARRAY_OF_DOUBLES
    Ein Array mit
    Fließkommazahlen.
    Lässt sich einfacher
    tippen als ARRAY<double>.

    CONTAINER
    Basis für die
    Containerklassen. Alles ist
    besser, wenn es nach Java
    riecht.

    DOUBLE_LIST
    Basis für alle Elemente der
    verketteten Liste. Mein
    Bewerbungsbeitrag zu the
    daily wtf.

    LIST_CONTAINER
    Container für eine
    verkettete Liste. Kann
    verschieden Objekte
    speichern, sie müssen nur
    von DOUBLE_LIST
    abgeleitet sein. Heute back
    ich, morgen brau ich und
    übermorgen schreibe ich ein
    Buch über Wurstbrote und
    Supermärkte.

    SIMPLE_SORTED_ARRAY<OBJ>
    Eine einfache sortierte
    Liste. Sie müssen keine
    Vergleichsfunktion
    angeben. Die eingebaute
    Vergleichsfunktion,
    erwartet, daß der Operator
    != -1 zurückliefert, wenn
    der linke Operand kleiner
    ist, 0 wenn beide gleich
    sind und +1 wenn der
    rechte Operand kleiner ist.
    Bazinga!

    RANDOM_ARRAY
    Wie ARRAY, aber nicht benutzte
    Elemente werden mit zufälligen
    Daten gefüllt.

    SORTED_ARRAY<OBJ>
    Ein Array, das sortiert
    werden kann.

    SORTED_CONTAINER
    Eine verkettete Liste, die
    sortiert werden kann.

    GcObject
    Basisklasse, für Objekte,
    die automatisch gelöscht
    werden können, wenn es
    keinen Zeiger mehr auf sie
    gibt.

    Prima, um in Erinnerungen zu schwelgen. Lange keinen so klaren 80-er-Jahre-Stil mehr gesehen.



  • Also was mich an der Lib besonders stoert, ist dass es keine Basisklasse OBJECT gibt, von der alle Klassen abgeleitet sind. Dadurch wirkt die Lib so inkonsistent.



  • Kellerautomat schrieb:

    Also was mich an der Lib besonders stoert, ist dass es keine Basisklasse OBJECT gibt, von der alle Klassen abgeleitet sind. Dadurch wirkt die Lib so inkonsistent.

    Viel mehr fehlt eigentlich RANDOM_OBJECT.

    @volkard Danke für die Arbeit. 😃

    @TE Heißt "intern" der Kram steht tatsächlich in irgendeinem Programm? Der wird benutzt?^^



  • volkard schrieb:

    Highlights (mit kleinen Einfügungen):

    ARRAY<OBJ>
    Ein dynamisches Array.
    Beim Zugriff auf ein Index,
    der noch nicht exisitert,
    wird einfach das Array
    entsprechend erweitert.
    Wir wollen nämlich Logikfehler
    vertuschen, statt sie zu behandeln.

    Stimmt, das ist ein Punkt, der mich auch immer wieder nervt. Vor allen, weil der operator [] daher nicht const sein darf.

    volkard schrieb:

    SEARCHABLE_ARRAY<OBJ>
    Ein Array, das durchsucht
    werden kann. <algorithm>
    ist nämlich total doof.

    Viele Klassen sind sehr alt, da gab's noch keinen C++ ISO Standard.

    volkard schrieb:

    ARRAY_OF_DOUBLES
    Ein Array mit
    Fließkommazahlen.
    Lässt sich einfacher
    tippen als ARRAY<double>.

    Der kann aber weder 'nen Mittelwert noch die Summe bilden.

    volkard schrieb:

    RANDOM_ARRAY
    Wie ARRAY, aber nicht benutzte
    Elemente werden mit zufälligen
    Daten gefüllt.

    Wozu das?

    volkard schrieb:

    Prima, um in Erinnerungen zu schwelgen. Lange keinen so klaren 80-er-Jahre-Stil mehr gesehen.

    90er Jahre bitte. In den 80er habe ich mit C++ noch nix am Hut gehabt.

    mfg Martin



  • Kellerautomat schrieb:

    Also was mich an der Lib besonders stoert, ist dass es keine Basisklasse OBJECT gibt, von der alle Klassen abgeleitet sind. Dadurch wirkt die Lib so inkonsistent.

    Warum?



  • cooky451 schrieb:

    Kellerautomat schrieb:

    Also was mich an der Lib besonders stoert, ist dass es keine Basisklasse OBJECT gibt, von der alle Klassen abgeleitet sind. Dadurch wirkt die Lib so inkonsistent.

    Viel mehr fehlt eigentlich RANDOM_OBJECT.

    Was sollte dies tun?

    cooky451 schrieb:

    @volkard Danke für die Arbeit. 😃

    @TE Heißt "intern" der Kram steht tatsächlich in irgendeinem Programm? Der wird benutzt?^^

    Klar wird die benutzt. Der XSLT-Prozessor funkt auch recht gut.

    mfg Martin



  • mgaeckler schrieb:

    Kellerautomat schrieb:

    Also was mich an der Lib besonders stoert, ist dass es keine Basisklasse OBJECT gibt, von der alle Klassen abgeleitet sind. Dadurch wirkt die Lib so inkonsistent.

    Warum?

    dein Ironie-Detektor ist kaputt.

    mgaeckler schrieb:

    Viele Klassen sind sehr alt, da gab's noch keinen C++ ISO Standard.

    Heute gibt es aber den Standard und heutige Programme sollten diesen auch nutzen. Warum sollte jemand bspw. Interese an deinem STRING haben, wenn er doch std::string verwenden kann?

    Ich habe ganz bestimmt kein Interesse an einer Bibliothek, die im Programmierstil der 90er aufgebaut ist.



  • volkard schrieb:

    Highlights (mit kleinen Einfügungen):

    ...

    Prima, um in Erinnerungen zu schwelgen. Lange keinen so klaren 80-er-Jahre-Stil mehr gesehen.

    YMMD 😃



  • daddy_felix schrieb:

    mgaeckler schrieb:

    Kellerautomat schrieb:

    Also was mich an der Lib besonders stoert, ist dass es keine Basisklasse OBJECT gibt, von der alle Klassen abgeleitet sind. Dadurch wirkt die Lib so inkonsistent.

    Warum?

    dein Ironie-Detektor ist kaputt.

    Meiner funktioniert. Aber wie sieht's mit Deinem aus 😃

    daddy_felix schrieb:

    mgaeckler schrieb:

    Viele Klassen sind sehr alt, da gab's noch keinen C++ ISO Standard.

    Heute gibt es aber den Standard und heutige Programme sollten diesen auch nutzen. Warum sollte jemand bspw. Interese an deinem STRING haben, wenn er doch std::string verwenden kann?

    Ich habe ganz bestimmt kein Interesse an einer Bibliothek, die im Programmierstil der 90er aufgebaut ist.

    Stimmt, für die Container- und Stringklassen bietet der Standard gleichwertigen Ersatz. Soll ich aber diese Klassen in der Doku deshalb ignorieren?

    Interesant könnte aber die Bibliothek wegen dem XML-, HTML-, CSS-, HTTP-, XSLT-, XSchema- und XPath-Zeugs etc. sein. Oder bietet der Standard dafür auch Lösungen? Aber ich sehe schon, ich kann mir wohl die weitere Mühe sparen, das Ding zu veröffentlichen. Hab ich auch kein Problem damit. 👍

    mfg Martin



  • mgaeckler schrieb:

    Stimmt, für die Container- und Stringklassen bietet der Standard gleichwertigen Ersatz. Soll ich aber diese Klassen in der Doku deshalb ignorieren?

    Nein, nicht ignorieren. Du sollst sie aus der Lib komplett rausschmeißen und stattdessen die Standard-Klassen verwenden.



  • daddy_felix schrieb:

    mgaeckler schrieb:

    Stimmt, für die Container- und Stringklassen bietet der Standard gleichwertigen Ersatz. Soll ich aber diese Klassen in der Doku deshalb ignorieren?

    Nein, nicht ignorieren. Du sollst sie aus der Lib komplett rausschmeißen und stattdessen die Standard-Klassen verwenden.

    Für Container kann dies wahrscheinlich sogar mit vertretbaren Aufwand gemacht werden. Bei STRING wird's schon etwas aufwendiger, da STRING-Objekte wissen, ob Umlaute ANSI-kodiert oder UTF-8 kodiert werden müssen. Datei-operationen wissen das auch und verwenden unter Windows dann die entsprechenden wchar_t bzw. Unicode varianten. Beispiel:

    strFiles.h:

    #ifndef __GNUC__
    int strStat( const STRING &path, struct stat *statbuff );
    #else
    inline int strStat( const STRING &path, struct stat *statbuff )
    {
    	return stat( path, statbuff );
    }
    
    #endif
    

    strFiles.cpp:

    int strStat( const STRING &path, struct stat *statbuff )
    {
    	int	result;
    
    	if( path.getCharSet() == STR_UTF8 )
    	{
    		uSTRING	wPath;
    
    		wPath.decodeUTF8( path );
    #if defined( __BORLANDC__ )
    #	if __BORLANDC__ > 0x0520
    		result = _wstat( wPath.getString(), (struct _stat *)statbuff );
    	#else
    		result = _wstat( wPath.getString(), statbuff );
    	#endif
    #elif defined _MSC_VER
    		struct _stat64i32	vs2010Buff;
    		result = _wstat( wPath.getString(), &vs2010Buff );
    		statbuff->st_atime = vs2010Buff.st_mode;
    		statbuff->st_ctime = vs2010Buff.st_ctime;
    		statbuff->st_dev = vs2010Buff.st_dev;
    		statbuff->st_gid = vs2010Buff.st_gid;
    		statbuff->st_ino = vs2010Buff.st_ino;
    		statbuff->st_mode = vs2010Buff.st_mode;
    		statbuff->st_mtime = vs2010Buff.st_mtime;
    		statbuff->st_nlink = vs2010Buff.st_nlink;
    		statbuff->st_rdev = vs2010Buff.st_rdev;
    		statbuff->st_size = vs2010Buff.st_size;
    		statbuff->st_uid = vs2010Buff.st_uid;
    #endif
    
    	}
    	else
    	{
    		result = stat( path, statbuff );
    	}
    
    	return result;
    }
    

    std::string kann das meines Wissens von sich aus nicht. Also brauche ich dafür sowieso eine eigene Klasse.

    mfg Martin



  • Dir ist aber bewusst, dass man in C++ freie Funktionen schreiben kann, um Funktionalität bestehender Klassen zu erweitern? Dass man 5 Klassen für sortierbare, zufällig füllbare, mittelwert-berechenbare, selbst-erweiternde und nichtskönnende Container schreibt, ist absoluter Unsinn.

    Schau dir vielleicht mal die STL-Algorithmen an. Dann wird dir bewusst, warum die STL derart mächtig ist, obwohl die einzelnen Container relativ wenige Operationen anbieten.



  • Naja, Unicode ist trotzdem tricky.
    Ich hab mir auch eigene String-Klassen und IOStreams geschrieben, die mit Multibytenecodings klar kommen.
    Ich habe allerdings trotzdem so viel wie möglich von der STL genutzt.



  • Nexus schrieb:

    Dir ist aber bewusst, dass man in C++ freie Funktionen schreiben kann, um Funktionalität bestehender Klassen zu erweitern? Dass man 5 Klassen für sortierbare, zufällig füllbare, mittelwert-berechenbare, selbst-erweiternde und nichtskönnende Container schreibt, ist absoluter Unsinn.

    Schau dir vielleicht mal die STL-Algorithmen an. Dann wird dir bewusst, warum die STL derart mächtig ist, obwohl die einzelnen Container relativ wenige Operationen anbieten.

    Ohne den Code jetzt schönreden zu wollen, aber wenn das Zeugs gewachsen ist kann ich das schon nachvollziehen. Zuerst kam die Anforderung, prä-standard eine Containerklasse zu bauen: Zack, fertig. Danach kam die Änderung, dass der Container sortierbar sein soll: Memberfunktion hinzugefügt, fertig. Und so nimmt das Unheil seinen Lauf, man erweitert und spezialisiert ohne klares Konzept und hinterher hat man X Klassen, die alle Ähnliches tun, aber doch unterschiedlich sind. Und wenn das Zeugs erst ein mal im Produktivcode eingesetzt wird tut man sich schwer damit, das Interface zu ändern.

    Vor 20 Jahren hätte ich mir vielleicht überlegt, das einzusetzen, aber heute mit der STL und boost: Nein, danke.



  • Nexus schrieb:

    Dir ist aber bewusst, dass man in C++ freie Funktionen schreiben kann, um Funktionalität bestehender Klassen zu erweitern? Dass man 5 Klassen für sortierbare, zufällig füllbare, mittelwert-berechenbare, selbst-erweiternde und nichtskönnende Container schreibt, ist absoluter Unsinn.

    Schau dir vielleicht mal die STL-Algorithmen an. Dann wird dir bewusst, warum die STL derart mächtig ist, obwohl die einzelnen Container relativ wenige Operationen anbieten.

    Was ist besser?

    class ARRAY_OF_DOUBLES : public ARRAY<double>
    {
    	public:
    	double sum( void ) const;
    	double average( void ) const
    	{
    		return sum() / (double)getNumElements();
    	}
    };
    

    oder

    double sum( ARRAY<double> &array );
    double average( ARRAY<double> &array ) const;
    

    OK letzteres könnte man auch über templates realisieren, um dann nicht nur doubles zu summieren sondern auch ints oder Äpfel. Aber solange das nicht notwendig ist, ist das egal. Mir gefällt ersteres dabei besser.

    Die STL muß halt viele Bedürfnisse erfüllen können. Klar ist die dadurch viel mächtiger wie meine Bibliothek.

    mfg Martin



  • mgaeckler schrieb:

    Was ist besser?

    class ARRAY_OF_DOUBLES : public ARRAY<double>
    {
    	public:
    	double sum( void ) const;
    	double average( void ) const
    	{
    		return sum() / (double)getNumElements();
    	}
    };
    

    oder

    double sum( ARRAY<double> &array );
    double average( ARRAY<double> &array ) const;
    

    OK letzteres könnte man auch über templates realisieren, um dann nicht nur doubles zu summieren sondern auch ints oder Äpfel. Aber solange das nicht notwendig ist, ist das egal. Mir gefällt ersteres dabei besser.

    Es ist ganz klar das zweite besser.
    z.B. schonmal deswegen, weil du damit keine Probleme bekommst wenn du mal ein ARRAY<double> statt eines ARRAY_OF_DOUBLES übergeben bekommst, und dann sum oder average drauf machen willst.



  • DocShoe schrieb:

    Ohne den Code jetzt schönreden zu wollen, aber wenn das Zeugs gewachsen ist kann ich das schon nachvollziehen.

    Das war aber nicht die Frage, die Frage war ob Interesse an der Library bestehen könnte.
    Und die Antwort darauf ist wohl nicht abhängig davon wie und warum die Library gewachsen ist.



  • mgaeckler schrieb:

    double sum( ARRAY<double> &array );
    double average( ARRAY<double> &array ) const;
    

    Wenn überhaupt dann mit const reference. Wie kommt das, dass Du eine zig Jahre an einer Klassenbibliothek arbeitest und noch nicht mal const correctness verstehst? Ich würde so eine Klassenbibliothek nicht weiter anschauen, wenn der Autor so wenig C++-Know-How zeigt. Entschuldige die scharfen Worte aber manchmal ist es besser direkt zu sein.

    Und übrigens: Statt einen konkreten Containertyp zu übergeben, solltes Du entweder einen Container über Template definieren oder gleich Iteratoren übergeben. Dann wird es generisch. Es schadet ja nicht, wenn die sum Funktion mehr kann, als für den aktuellen Anwendungsfall notwendig ist. Insbesondere wenn die sum Funktio bestandteil einer Bibliothek sein soll.



  • DocShoe schrieb:

    Ohne den Code jetzt schönreden zu wollen, aber wenn das Zeugs gewachsen ist kann ich das schon nachvollziehen.

    Nachzuvollziehen, wie sowas vor zwei Jahrzehnten entstanden ist, ist das eine, aber diese Bibliothek im Jahre 2014 noch zu verteidigen braucht doch einiges an Mut 😉

    mgaeckler schrieb:

    Mir gefällt ersteres dabei besser.

    Warum? Wegen der Syntax?

    D.h. du schränkst die Berechnung des Mittelwertes auf Klassen ein, die genau dafür konzipiert wurden, und machst alle anderen inkompatibel? Wie mit Java-Interfaces?
    Und wenn du nun das Maximum berechnen willst, leitest du eine neue Klasse ab? Und für das Produkt der Elemente ebenfalls?

    Edit: hustbaer, habe erst jetzt gesehen dass du das korrigiert hast. Darum Quote geändert.


Anmelden zum Antworten