ist Sub-Pointer möglich



  • Hallo,

    ich hab da was gebaut, was mich nicht glücklich macht, und überaus unelegant ist. Deshalb möchte ich fragen ob jemand eine offizielle Adressierungsart kennt, die ich benützen könnte:

    Ich hab eine Anwendung programmiert mit mehreren Fenstern. Jedes Fester hat einen Datensatz (struct) der relevantes steuert. Jetzt möchte ich vom Hauptfenster aus alle SubFenster bearbeiten:

    AktivesFenster->Steuererung.Opt_a
    

    so kann ich einzelne Datenfelder im Struct perfekt adressieren. Jetzt habe ich aber mehrere von Opt_a bis Opt_z, und möchte diese in einer Loop bearbeiten. Eine Arraylösung scheidet aus.

    Am liebsten wäre mir sowas:

    AktivesFenster->Steuererung.Pointer_to_Opt
    

    gibt es sowas?
    Gruß Rudi



  • rudiM schrieb:

    Eine Arraylösung scheidet aus.

    Du brauchst keine Arrays. Dennoch wäre es gut, wenn du sagen könntest, was dich daran stört. 😉

    Am naheliegendsten scheinen mir für dein Problem die STL-Container. Dann kannst du bequem durch alle Instanzen durchiterieren oder sogar funktionale Algorithmen wie std::for_each() verwenden.



  • Falls alle Member den gleichen Datentyp haben, kannst du einfach eine union mit einem Array machen.



  • Hallo,

    das mit der union scheint mir möglich zu sein. Ich kann meine Struct (sie hat auch noch viele andere Datentypen) unverändert lassen (ich hab schon zuviel programmierarbeit investiert) und trotzdem Arrayfunktionen verwenden. Ich probiers mal.

    Danke Rudi.



  • Erstell doch eine Liste mit Zeigern auf die Optionen. Dann kannst du da gemütlich drüber iterieren und tun und lassen, was du willst.



  • rudiM schrieb:

    das mit der union scheint mir möglich zu sein. Ich kann meine Struct (sie hat auch noch viele andere Datentypen) unverändert lassen (ich hab schon zuviel programmierarbeit investiert) und trotzdem Arrayfunktionen verwenden.

    Nimm Unions, Structs und Arrays, wenn du C programmieren willst. Ich dachte eigentlich, du wolltest eher eine elegante C++-Lösung...

    drakon rät auch zu Listen, also wird da schon was dran sein, meinst du nicht? Falls nein, erklär doch wieso nicht, dann können wir immer noch bessere Vorschläge geben.



  • Ja, union ist wohl nicht C++,

    Ich könnte ja wirklich eine Pointerliste auf die Daten erstellen. Aber dann brauch ich für jedes Fenster eine Liste, oder? Wenn ich das vermeiden will, was mich zur ursprünglichen Frage führt, bräuchte ich für die Variablen ein Displacment, berechnet vom Structuranfang aus. Das ist, was ich momentan getan habe, aber scheiß unübersichtlich ist.
    Was natürlich hinterlich ist, ist dass ich an diesem Projekt schon 5 Jahre arbeite (nicht vollzeit), und nicht der unbedingte C++ Freakt war und bin. Von C++ nahm ich nur was ich brauchen konnte, ansonsten halt C. Vielleicht sind die beiden sich zu ähnlich, so dass ich nicht gezwungen wurde, komplett umzudenken. Ich geh halt momentan den Weg des geringsten Widerstandes, aber mir ist schon bewusst: ich nutze all die schönen C++ Features nicht aus.

    Rudi



  • rudiM schrieb:

    Ja, union ist wohl nicht C++,

    Sie sind Sprachbestandteil, wie auch goto , Makros usw. Aber das heisst ja noch lange nicht, dass man es unbedingt benutzen sollte, wenn es bessere Alternativen gibt.

    Ich könnte ja wirklich eine Pointerliste auf die Daten erstellen. Aber dann brauch ich für jedes Fenster eine Liste, oder?

    Die Frage ist, warum du das vermeiden möchtest. Das ist imo der portabelste und sicherste Weg. Da irgendwas auf Low Level mit offsets vom Anfang des structs machen zu wollen halte ich für gefährlich und unnötig.



  • Sag mal, jetzt komm ich ins philosofieren:

    struct und class sind sich ähnlich. Wenn nun aus meiner struct eine class mache, kann ich auch methoden dazu basteln. Ich bin mir nur nicht im klaren, was passiert, wenn ich eine class in einem File speichern will - beim struct sind es halt nur die Daten.

    Rudi



  • rudiM schrieb:

    struct und class sind sich ähnlich.

    Sie sind gleich. (Bis auf den Standardmässigen Zugriffsrechte).

    Wie das mit dem Speichern aussieht ist Sache, wie du das speicherst..



  • rudiM schrieb:

    AktivesFenster->Steuererung.Opt_a
    

    wenn die variablen der reihe nach im speicher liegen, a, b, c, d, ...
    und das padding ausgeschaltet ist, dann kannst du ohne probleme einen zeiger
    erstellen:

    int *opts = &AktivesFenster->Steuerererererung.Opt_a;
    
    opts[4] = 0; // greift auf Opt_a + 4 = Opt_e zu
    

    ansonsten ist eine union wirklich ein vollkommen vernünftiges mittel, solange alle
    vom selben typ sind.

    keine ahnung wieso wir jetzt wiedermal über struct und class philosophieren,
    aber solange du keine virtuellen methoden einbaust, wird deine struct/class
    nicht größer, kann also in die datei geschrieben werden.



  • Hallo kekz,

    klingt interessant. Aber wo/wie kann man bei BCC2009 das Padding ausschalten? Funktioniert das dann auch mit:

    MyClass *opts = &AktivesFenster->Steuererung.Opt_a
    

    Ich merke es schon, ich bin stark am lernen hier. Das wäre vielleicht die einfachste Änderung am Programm.
    liebe Grüße an Alle
    Rudi



  • Schau dir mal die '#pragma pack' Option an. Diese mußt du aber um deine Struktur herum benutzen.

    Ich würde dir aber auch zu einem Array raten (evtl. mit enum für die Parameterbenennung:

    enum Options ( opt_a, opt_b, ..., MaxOptions };
    
    struct Steuerung
    {
      TypeOfOptions options[MaxOptions];
    };
    
    // Zugriff:
    for(int i=0; i<MaxOptions; i++)
      TypeOfOptions& opts = &AktivesFenster->Steuerung.options[i];
    


  • Hallo,

    ich merk schon, es gibt einen Sack voll Lösungsmöglichkeiten. Ich muss jetzt nur noch sehen, welche am wenigsten Arbeit macht, meine 20.000 Codezeilen anzupassen, in denen diese Struct sehr oft auftritt.

    Ich danke meinen Ratgebern
    Rudi



  • rudiM schrieb:

    Ich merke es schon, ich bin stark am lernen hier. Das wäre vielleicht die einfachste Änderung am Programm.

    Wahrscheinlich auch die am wenigsten nachhaltige. Informier dich mal über undefiniertes Verhalten. Spätestens wenn du einmal sehr lange deswegen Fehler gesucht hast, wirst du dir wünschen, eine saubere Lösung gesucht zu haben. Aber du musst es ja wissen...

    Klar ist es mühsam, viele Codezeilen anzupassen. Eventuell machst du es diesmal noch auf die schnelle Art. Aber vor allem wenn du von C kommst, solltest du dir unbedingt die Zeit nehmen, moderne C++-Features anzuschauen, auch wenn sie in diesem Projekt nicht mehr gross zur Anwendung kommen. C-Programmierer tendieren nämlich stark dazu, ihre alten Programmiertechniken unverändert weiterzubenutzen, weil diese "ja weiterhin funktionieren". Trotzdem gibt es sehr viele C++-Konstrukte, die dir eine komfortable und vor allem sichere Datenverwaltung ermöglichen. Wenn du dir diese Mühe nicht machen willst, nutzt du sehr wichtige Vorzüge von C++ nicht - am meisten davon Abstraktion.


Anmelden zum Antworten