typedef und pointer



  • Hi alle,

    //code snippet
    typedef int* intptr;
    intptr myintptr;

    und dann will ich mit myintptr arbeiten, aber wie soll ich myintptr betrachten: als pointer? auf was? auf int?!?!
    aber warum kann ich nicht sagen:
    intptr myintptr = new intptr;
    wie wir es machen mit int:
    int* myintptr = new int; ???

    bitte vielleicht eine kurze Erklärung zu den oberen Unklarheiten.
    😕

    danke,
    memo



  • wenn du schreibst
    intptr myintptr = new intptr
    ist das doch das selbe wie
    int* myintptr = new int*
    und das geht nicht.
    (du weisst dem int pointer eine adresse auf einen
    pointer zu)



  • du schreibst ja auch nicht

    int myintptr = new int;
    


  • Korrekt müßtest du schreiben:

    intptr myint = new int;
    

    Aber das hier ist IMHO klarer (und kürzer 😉 )

    int* myint = new int;
    


  • IMHO geht die Unsitte, erstmal pauschal alles mögliche zu typedefinieren, auf Pascal zurück, in der man mit (wie soll ichs nennen) zusammengesetzten oder qualifizierten Typen wie int* nicht arbeiten konnte, sondern erst einen neuen benannten Typ dafür definieren mußte. Viele sogenannte alte Hasen sind in Wirklichkeit Pascal-Programmierer, die seitdem nicht viel dazugelernt haben. In C und C++ sollte man das nicht machen.



  • Original erstellt von Bashar:
    In C und C++ sollte man das nicht machen.

    Manchmal macht es aber Sinn, z.B. wenn es zu unleserlich wird

    typedef std::vector<std::string> string_vector
    

    oder falls der Typ dahinter nicht interessiert...

    typedef unsigned int size_type
    

    Ist aber Ansichtssache.

    😉



  • dazu fällt mir etwas aus dem CUJ ein:

    typedef int* intptr;
    
    void foo(const intptr p)
    {
      *p=bar(); //erlaubt oder nicht? und warum?
    }
    


  • ist doch ein int * const



  • MastaH: Ich hab lange überlegt, ob ich das Wort "pauschal" in Fettdruck setzen soll, damit solche Kommentare überflüssig werden. War wohl umsonst 😉



  • Original erstellt von Bashar:
    MastaH: Ich hab lange überlegt, ob ich das Wort "pauschal" in Fettdruck setzen soll, damit solche Kommentare überflüssig werden. War wohl umsonst 😉

    Da hab ich wohl beim lesen am Ende des Beitrages nicht mehr gewusst was am Anfang stand... Jetzt wo du es sagst. 🙄 😉



  • Original erstellt von Shade Of Mine:
    ***p=bar(); //erlaubt oder nicht? und warum?
    **

    Warum sollte das nicht erlaubt sein? Das p ist doch ein const int* wie fisch schon gesagt hat! Dann ist das doch eigentlich erlaubt.



  • Original erstellt von MaSTaH:
    Warum sollte das nicht erlaubt sein? Das p ist doch ein const int wie fisch schon gesagt hat! Dann ist das doch eigentlich erlaubt.*

    also wenn p ein const int* wäre, dann wäre es nicht erlaubt.
    aber tatsächlich ist p ein int* const wie fisch ja schon sagte.

    deshalb ist es auch unmöglich einen typedef auf T* wie einen const T* zu behandeln -> man braucht ein zweites typedef auf const T*

    deshalb: nie Zeiger typedefen - nur den typen dahinter (unter rücksichtnahme auf Bashars einwurf)



  • Original erstellt von Shade Of Mine:
    also wenn p ein const int wäre, dann wäre es nicht erlaubt.
    aber tatsächlich ist p ein int
    const wie fisch ja schon sagte.**

    Äh, mein ich ja 🙄 . *verdreh* 😉

    [ Dieser Beitrag wurde am 06.04.2003 um 20:00 Uhr von MaSTaH editiert. ]



  • Original erstellt von Shade Of Mine:
    deshalb: nie Zeiger typedefen

    Doch, doch. Als Iterator macht man das im Trivialfall ständig. Ich behaupte viel lieber: nie Arrays typedefen.



  • Original erstellt von Daniel E.:
    Doch, doch. Als Iterator macht man das im Trivialfall ständig. Ich behaupte viel lieber: nie Arrays typedefen.

    iterator ist IMHO etwas anderes weil es eine abstraktion ist.
    ob hinter iterator jetzt T* oder class iterator steckt ist egal, es muss sowieso einen const_iterator geben.

    aber ich bin sicher, du hast noch n anderes beispiel wo man einen T* typedeft, stimmts?



  • Es geht doch bei typedef immer um Abstraktion im weitesten Sinne. Ich möchte einen Typen möglichst schnittstellentransparent austauschen können.

    Beispiele für getypedefte Zeiger gibt's wie Sand am Meer: »typedef void (*fun)(int);«. Mehr fällt mir gerade mal nicht ein, ist aber auch nicht schlimm; schlimm fände ich es eher, wenn C++ mit einer Datenbank von paxisrelevanten Anwendungsfällen daherkäme und mir dann erzählen würde, getypedefte Zeiger sein blöd.

    Mal ein Ansatz zu einer Stringbibliothek, die Nullen ('\0') enthalten darf (Vorsicht, kein wirkliches C++, sondern ein ungetestetes C):

    typedef int       *string;
    typedef int const *const_string;
    
    /* ... */
    
    size_t lenstr(const_string str)
    {
        const_string begin;
    
        begin = str;
        while (*str >= 0) ++str;
        return str - begin;
    }
    

    Irgendwann stellt man dann schon fest, dass ein

    typedef struct string {
        size_t len;
        unsigned char* string;
    } string;
    
    /* ... */
    
    #define lenstr(s) ((s).len)
    

    vielleicht doch schöner sein könnte... Um mal ein Beispiel zu nehmen, dass in der Realität nicht vorkommen wird und damit von Anwendungsfallerkenner zuverlässig eliminiert werden kann.


Anmelden zum Antworten