struct-Zugriff auf verschiedene structs über einen Zeiger



  • Hallo Gemeinschaft,

    ich möchte gerne in einer Methode über einen Zeiger auf verschieden aufgebaute Strukturen bzw. deren Elemente zugreifen. Da sich viele Elemente der Strukturen gleichen, möchte ich gerne alle Strukturen in einer einzigen Methode bearbeiten. Die Bearbeitung / Auslassung ungleicher Strukturelemente würde ich mittels Abhängigkeiten steuern. So sieht es bisher aus:

    void TFormA::StructAccess(void* pSourceStruct, bool bAbh1, bool bAbh2)
    {
        typedef TFormB::StructA Typ1;                             // typedef nur für kürzere Schreibweise im weiteren Code
        typedef TFormB::StructB Typ2;
        typedef TFormB::StructC Typ3;
        typedef TFormB::StructD Typ4;
        int iSrcID= bAbh1 ? (bAbh2 ? 0 : 2) : (bAbh2 ? 1 : 3);
        void* pSrc;
        switch(iSrcID){
            case 0: pSrc= (Typ1*)pSourceStruct; break;
            case 1: pSrc= (Typ2*)pSourceStruct; break;
            case 2: pSrc= (Typ3*)pSourceStruct; break;
            case 3: pSrc= (Typ4*)pSourceStruct; break;
        }
        pSrc->GleichesElementInAllenStruct[0]= '1';               // Fehler, da pSrc vom Typ void*
        //...
        if(Abh1 && Abh2){
            pSrc->ElementNurInStructA[0]= '2';                    // Fehler, da pSrc vom Typ void*
        }
        //...
    }
    //----------------------------------------------------------------------------------------
    

    Nun müsste ich dem Compiler irgendwie klarmachen, dass pSrc vom Typ "ZeigerAufDieJeweiligeStruktur" ist. Ist das realisierbar? Falls ja, wie kann das aussehen?
    Danke für alle Hinweise!

    MfG



  • Sorry Kolumbus, soweit solltest du eigentlich mit C++ sein: Namen sind Schall und Rauch...

    Du könntest zwar Template-Funktionen dafür benutzen, jedoch halte ich dein Vorgehen alleine schon für sehr fragwürdig.

    Warum hast du überhaupt verschiedene (voneinander unabhängige) Strukturen, wenn du doch dieselben Funktionalitäten damit ausführen willst??? Könntest du die Strukturen nicht von einer Basisklasse erben lassen?

    Am besten, du zeigst mal den Aufbau deiner Strukturen...



  • Ich wusste dass die Antwort so aussehen würde 🙂 Das ursprüngliche Programm ist nicht von mir. Würdest du den kompletten Programmcode sehen, würden sich deine Fussnägel hochkrempeln und spontan dein Augenlicht verlöschen! Ich habe mir die Strukturen nicht ausgedacht und kann sie jetzt nicht ändern, weil ich dann gleich ein neues Prog schreiben könnte. Ich soll das Programm betreuen. Ich will es jetzt immer wenn ich mal Zeit habe etwas übersichtlicher gestalten, diesmal eben eine bestimmte Bearbeitung von 4 Strukturen, die derzeit über 4 Methoden läuft die jeweils exakt einmal im Code aufgerufen werden. Das finde ich irgendwie schwachsinnig und deshalb will ich jetzt einfach aus 4 Methoden 1 Methode machen...

    In diesem Sinne:

    Th69 schrieb:

    Namen sind Schall und Rauch...

    Aber Typen nicht und da liegt nun, wie schon gesagt, mein Problem!

    Th69 schrieb:

    Du könntest zwar Template-Funktionen dafür benutzen, jedoch halte ich dein Vorgehen alleine schon für sehr fragwürdig.

    Ich halte das komplette Programm für fragwürdig... nein, sogar für komplett Sch**sse! 😉

    Th69 schrieb:

    Am besten, du zeigst mal den Aufbau [der] Strukturen...

    mal symbolisch:

    typedef struct{
        charArray[20] Element1;
        charArray[30] Element2;
        charArray[10] Element3;
        charArray[20] Element4;
        int Element5;
        int* Element6;
    }StructA;
    typedef struct{
        charArray[20] Element1;
        charArray[30] Element2;
        charArray[10] Element3;
        charArray[20] Element4;
        int Element5;
        int Element6;
    }StructB;
    typedef struct{
        charArray[20] Element1;
        charArray[30] Element2;
        charArray[10] Element3;
        charArray[20] Element4;
        int Element5;
        bool Element6;
    }StructC;
    typedef struct{
        charArray[20] Element1;
        charArray[30] Element2;
        charArray[10] Element3;
        charArray[20] Element4;
        int Element5;
        long[5] Element6;
    }StructD;
    

    Das kommt der Wahrheit schon ziemlich nahe, nur vom Umfang her nicht 😉

    MfG



  • Th69's Idee ist doch gar nicht so schlecht. Wenn du viel ändern kannst, könnte man doch die gemeinsame Funktionalität in einer Basisklasse kapseln, die ableitenden Klassen könnten dann mit Schablonenmethoden die individuellen Probleme abbilden.



  • Mal abgesehen davon, dass ich eigentlich nur wissen wollte, ob und wie ich einen void-Zeiger vom Typ her auf einen Zeiger auf ein bestimmtes Objekt ändern kann:

    Ich habe mir mal 'template method ' bei wiki durchgelesen und denke es auch grob verstanden zu haben. Allerdings muss ich jederzeit damit rechnen dass ich plötzlich etwas Anderes zu tun habe, daher werde ich mich nebenbei erstmal mit der Theorie beschäftigen und überlegen, wie ich das Ganze sinnvoll ins Programm implementieren kann. Danke für den Hinweis, wenn ihr so darauf besteht muss ja was dran sein 😃

    Es wäre trotzdem schön, wenn mir mal jemand sagen kann, ob ich den Typ des Zeigers nachträglich ändern kann oder wie man in diesem Fall vorgehen könnte!

    Ach, wie blöd... mir fällt grad' ein, dass ich die Methode ja überladen könnte, um gleich Zeiger auf die verschiedenen Strukturen zu haben... Was meint ihr?



  • Hallo

    Du kannst mit entsprechenden Casts den Compiler jederzeit dazu zwingen, einen Speicherbereich mit einem anderen Typ zu behandeln. Mal in Kurzform :

    Typ1 a;
    Typ2* b = reinterpret_cast<Typ2*>(&a);
    // mit b arbeiten
    

    Das ist aber sehr gefährlich, da du damit ganz schnell ungültige Speicherzugriffe provozierst, die sehr schwer zu debuggen sind. Sowas solltest du nur machen, wenn du wirklich genau weißt was du tust. Templates und/oder Basisklassen sind eindeutig eleganter, sicherer und verständlicher.

    /Edit : In deinem Beispiel wären nur die ersten beiden structs miteinander binär kompatibel, und auch das nur auf 32-Bit System.
    Sowohl bool als auch long[5] ist haben meistens jeweils ein anderes Speicherlayout, konkret belegte Bytes. Vom struct-Alignment ganz zu schweigen.

    bis bald
    akari



  • Die Idee, die Methode zu überladen, finde ich richtig, würde ich sicherlich genauso machen.
    😉


Log in to reply