Konstante Zeiger als Parameter



  • typedef int* PINT;
    typedef const int* CPINT;
    

    😕



  • Ja klar, so würde das natürlich gehen. Aber es geht ja hier darum, daß der Zeigertyp von außerhalb bereits vorgegeben ist: Ich habe einen mit typedef definierten Typ PIRGENDWAS und hätte diesen nun in der Weise konstant, wie ich es oben beschrieben habe. Da ist es ja kein guter Stil, sich erstmal anzugucken, was dieser Typ ursprünglich überhaupt war, und nun einen eigenen typedef auf Grundlage des Originaltyps zu machen.



  • NES-Spieler schrieb:

    Mein konkretes Problem ist übrigens, wer es wissen will, daß ich in Windows eine Klasse habe, die mit Handles (HBITMAP, HDC, HWND, HINSTANCE) arbeitet. Und da Handles ja Zeiger sind (void *), würde ich das eben gern so machen, daß, wann immer sie als Parameter übernommen werden und nicht geändert werden sollen, der Wert, auf den sie zeigen, konstant ist.
    Irgendeine Möglichkeit muß es da doch geben, sonst wäre das echt ein fehlendes Feature.

    dass es ein void* ist, braucht eigentlich irgendwie nicht zu interessieren: denn der typ ist HBITMAP...

    man kann den inhalt des void* ja auch nicht so einfach aendern 😉 dazu muss man sowieso casten und dann geht das const sowieso weg (sind ja in der winapi alles c casts... die machen n const aus "versehen" weg).

    also passt schon. nenn es const HBITMAP und gut ist 🙂


  • Mod

    mit ein paar einfachen template metafunktionen ist das kein problem (ich benutze hier boosts typetraits, aber man kann sich das auch leicht selbst bauen).

    typedef const boost::remove_pointer<pointer2T>::type* pointer2constT;
    


  • NES-Spieler schrieb:

    Aber es geht ja hier darum, daß der Zeigertyp von außerhalb bereits vorgegeben ist.

    Genau darum geht es ja. Der Typ ist nunmal vorgegeben, also kannst du nur noch den Zeigertyp beeinflussen 😉



  • An Shade of Mine:

    const HBITMAP wäre ja wieder: Ich kann den Wert ändern, aber die Adresse nicht. In diesem Fall kann ich das const ja gleich weglassen, denn ob die Funktion intern den Zeiger verbiegen darf, ist nach außen hin sowieso unerheblich. Aber gerade das wollte ich nicht, sondern ich möchte es so machen, daß ein Außenstehender sieht, ob die Funktion intern den Wert ändern kann. (So wie in strcpy (char *, const char *): Da sieht man sofort: Der zweite Parameter wird nicht verändert. Und so wird das, soweit ich weiß, eigentlich fast überall geschrieben, wo Werte als Zeiger übergeben werden.)

    Und nochmal zu der Sache mit dem selbst Erstellen von Typen: Wir haben jetzt natürlich den Vorteil, daß ein void * alles sein kann, und man das ganze somit direkt codieren könnte. Aber meiner Meinung ist das nur eine Verdrängung, aber keine Lösung des Problems. Wie gesagt, man stelle sich vor, jemand stellt den Typ PZAHL zur Verfügung. Die Zahl wird nie direkt verändert oder ausgegeben, das machen alles Funktionen, die sie als Parameter entgegennehmen. (Ja, ich weiß, heutzutage würde man dann eine Klasse schreiben, deren Methoden diese Funktionen wären, aber nehmen wir es nur mal an.) Und nun schreibe ich:

    typedef const int *PCTZAHL
    

    . Spätestens, wenn der Programmierer für PZAHL eine Struktur nimmt, dürfte ich Probleme bekommen.

    Genau darum geht es ja. Der Typ ist nunmal vorgegeben, also kannst du nur noch den Zeigertyp beeinflussen

    Aber ich kann bei einem P_NICHT_NAEHER_ERKLAERTER_TYP keinen PCT_NICHT_NAEHER_ERKLAERTER_TYP deklarieren, der vom Ursprungstyp ausgeht, sondern muß den direkt auf P_NICHT_NAEHER_ERKLAERTER_TYP basieren lassen.



  • An camper:
    Soweit ich weiß, ist Boost (noch) kein Standard und ich benutze nicht so gerne Funktions- oder Klassensammlungen von außerhalb. Gibt es da ein Pendant in Standard-C++ (oder zumindest in der WinAPI), denn von so etwas habe ich noch nie gehört.



  • const FOO
    sagt dass du nicht
    foo=x
    machen kannst

    was HBITMAP jetzt intern ist, hat dich nicht zu interessieren, das ist abstraktion.

    es koennte zB morgen ein unsigned int sein und am tag darauf ein char* und am naechsten tag ne klasse...


  • Mod

    NES-Spieler schrieb:

    An camper:
    Soweit ich weiß, ist Boost (noch) kein Standard und ich benutze nicht so gerne Funktions- oder Klassensammlungen von außerhalb. Gibt es da ein Pendant in Standard-C++ (oder zumindest in der WinAPI), denn von so etwas habe ich noch nie gehört.

    das ist witzig, schließlich hat die WinAPI weitaus weniger mit standard C++ zu tun als boost 😉
    aber wie gesagt, das ganze kannst du dir auch selbst basteln:

    template<typename T>struct remove_pointer { typedef T type; };
    template<typename T>struct remove_pointer<T*> { typedef T type; };
    


  • was HBITMAP jetzt intern ist, hat dich nicht zu interessieren, das ist abstraktion.
    es koennte zB morgen ein unsigned int sein und am tag darauf ein char* und am naechsten tag ne klasse...

    Deswegen sag ich ja, daß die Variante von Neku

    typedef int* PINT; 
    typedef const int* CPINT;
    

    nicht geht, da sich das zweite typedef auf den neu erzeugten Typ und nicht auf den Originaltyp beziehen muß.

    das ist witzig, schließlich hat die WinAPI weitaus weniger mit standard C++ zu tun als boost

    Wie gesagt, meine Begründung war ja:

    ich benutze nicht so gerne Funktions- oder Klassensammlungen von außerhalb

    Die WinAPI ist zwar noch weitaus weniger Standard, aber sie ist zumindest in Visual C++ enthalten und ich muß nicht extra irgendwelche zusätzlichen Header und Libraries installieren. Aber das ist sowieso egal, denn von der WinAPI wird es für dieses Problem wohl keine Lösung geben. Deine Variante will ich mir mal ansehen, aber ich finde es noch immer ein Versäumnis, daß die Leute vom Standard-Kommitee offensichtlich keine Möglichkeit eingebaut haben, einen const typ * zu erzeugen, wenn typ * bereits als PTYP definiert ist.



  • NES-Spieler schrieb:

    Genau darum geht es ja. Der Typ ist nunmal vorgegeben, also kannst du nur noch den Zeigertyp beeinflussen

    Aber ich kann bei einem P_NICHT_NAEHER_ERKLAERTER_TYP keinen PCT_NICHT_NAEHER_ERKLAERTER_TYP deklarieren, der vom Ursprungstyp ausgeht, sondern muß den direkt auf P_NICHT_NAEHER_ERKLAERTER_TYP basieren lassen.

    Bei dir ist es aber so:

    EIN_TYP << int
    P_EIN_TYP << int*
    PC_EIN_TYP << hier möchtest du EIN_TYP (int) durch ein const erweitern
    und wenn ich mich nicht irre ist dies nicht möglich



  • Nicht mit nem normalen typedef

    Bei makros (MS Praxis) wuerde es dem Standard-Orientierten C++ Anwender die Schuhe ausziehen

    Den Typen in nen Wrapper kapseln und das ganze als Template waer unter c++ ne saubere Loesung, die scheint der Fragesteller aus diversen gruenden aber hartnaekisch zu ignorieren ^^

    Keine Ahnung was dann ueber bleibt.

    Ciao ...


Anmelden zum Antworten