[C++] constptr

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
Halan
Beiträge: 73
Registriert: 22.01.2005, 21:47
Benutzertext: programmiersüchtig
Echter Name: Kai Mast
Wohnort: Freak City
Kontaktdaten:

[C++] constptr

Beitrag von Halan »

Ahoi Leute,

ich war es Leid immer "const T* const" schreiben zu müssen und habe miri deswegen eine kleine Wrapper-Klasse geschrieben. Vielleicht finde die ja der ein oder andere ganz hilfreich.

Code: Alles auswählen

template<typename T> class constptr
{
public:
    constptr(const T* const data) : Data(data)
    {
    }

    template<typename C> constptr(const constptr<C>& other) : Data(dynamic_cast<const T* const>(other.Data))
    {
    }
    const T* const operator->() const
    {
        return Data;
    }

    const T& operator *()
    {
        return *Data;
    }

    bool operator==(const T* const other) const
    {
        return (other == Data);
    }

    bool operator==(const constptr<T>& other) const
    {
        return (other.Data == Data);
    }

    bool isNull() const
    {
        return (Data == nullptr);
    }

    const T* const Data;
}; 
Ich frage mich nur ob ich das irgendwie auch als typedef bauen kann. Gibt ja in C++11 template aliases aber die funktionieren in dem Fall wohl nicht.

mfg,
Halan
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: [C++] constptr

Beitrag von BeRsErKeR »

Ich frage mich ob Schreibaufwand eine Rechtfertigung für solch eine Implementierung ist, da du dir dadurch ja unnötigen Overhead einhandelst. Ganz zu schweigen davon, dass ich in vielen Jahren noch so gut wie nie etwas als const T * const anlegen musste. Bei Funktionsparametern bspw. macht das eine const in meinen Augen wenig Sinn und ansonsten nutze ich Pointer eh so selten wie möglich und wo sie nötig sind, ist eigentlich wenn dann nur der "Inhalt" oder nur der Zeiger an sich konstant. Sonst kann man damit nämlich wenig anfangen.

Aber vielleicht haben da ja andere Leute andere Erfahrungen gemacht.
Ohne Input kein Output.
Benutzeravatar
Schrompf
Moderator
Beiträge: 4864
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: [C++] constptr

Beitrag von Schrompf »

Ich dachte schon, ich wär wieder seltsam, nur weil ich das für Over Engineering halte. Entweder const T* oder (seltener) T* const - reicht doch.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: [C++] constptr

Beitrag von CodingCat »

Ich verstehe auch nicht, was du mit diesem Template bezweckst. Schon ein implizites dynamic_cast ist das Letzte, was ich wollte. Ein Wrapper bedeutet aber immer erstmal eine massive Funktionalitätseinschränkung (Hast du operator != als freies Template? Was ist mit Arrayzugriff? Willst du für Zugriff auf den Zeiger immer .Data schreiben? Ist das nicht viel umständlicher als einmal ein const an der richtigen Stelle?), potentielle Verhaltensänderung (siehe dynamic_cast) und somit auch Fehlerquellen. Obendrein werden die Fehlermeldungen undurchsichtig (bei Zuweisung bekommst du jetzt vermutlich irgendwas von nicht erzeugbaren Assignment-Operatoren anstatt Zuweisung auf einer const-Variablen). Der Name constptr ist für Dritte ebenfalls uneindeutig (Was ist const?) und verschlechtert somit die Lesbarkeit. (Was bedeutet const const_ptr<T>? Nichts, aber ist das intuitiv?)

Nebenbei bemerkt fehlt deinem Template wohl zumindest noch ein const bei operator *. ;)
BeRsErKeR hat geschrieben:Ich frage mich ob Schreibaufwand eine Rechtfertigung für solch eine Implementierung ist, da du dir dadurch ja unnötigen Overhead einhandelst.
Laufzeit-Overhead in einem normal optimierten Build allerdings nicht, nur damit das hier nicht zu Missverständnissen bzgl. der Effizienz von C++ führt.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: [C++] constptr

Beitrag von BeRsErKeR »

CodingCat hat geschrieben:Der Name constptr ist für Dritte ebenfalls uneindeutig (Was ist const?) und verschlechtert somit die Lesbarkeit. (Was bedeutet const const_ptr<T>? Nichts, aber ist das intuitiv?)
Wo du das gerade sagst. Ich kann dem aus gegebenen Anlass nur beipflichten. Ich durfte mir heute Mischmasch-Code aus einem ziemlich bekannten großen Softwareprojekt ansehen, was über rund 12 Jahre gewachsen ist. Es arbeitet mit den MFC. Da gibt es Funktionsparameter wie LPCTSTR &strFile. Zweck ist es eigentlich den Inhalt von strFile in der Funktion zu füllen. Dumm nur, dass sich hinter LPCTSTR ein const-Pointer verbirgt. Was nun gemacht wurde grenzt an Masochismus: Nach mehrmaligem Durchreichen wird strFile auf einen void-Pointer gecastet und über die Funktion free freigegeben und dann über eine ominöse dup-Funktion auf ein CString-Objekt neu initialisiert. Abgesehen von den etliche goto's, die alle eh nur zu einem return FALSE; springen, war das heute echt das Traurigste was ich gesehen habe.

Meine Vermutung ist, um wieder zum Thema zurückzukehren, dass irgendein schlauer Mensch optimieren wollte und dachte "Oh Referenzen sind immer gut". Ein CString & strFile wäre ja ok gewesen, nur wird er nicht verstanden haben, was sich hinter LPCTSTR verbirgt. Noch trauriger ist allerdings, dass ein andere Parameter direkt daneben wirklich ein CString war...
Ohne Input kein Output.
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: [C++] constptr

Beitrag von CodingCat »

Naja, MFC ist wenigstens der richtige Rahmen für solche Schweinereien. ;) Die Fehlerbehandlung mit goto scheint tatsächlich einigermaßen verbreitet zu sein, auch bei MS (z.B. Effects 11 Source Code, womöglich das ganze DirectX SDK?!). Aber da Exceptions nicht standardisiert sind, ist Fehlerbehandlung in geschlossenen Bibliotheken tatsächlich ein Problem. Die beste Lösung, die mir dazu bis jetzt eingefallen ist, wäre:

Code: Alles auswählen

ErrorType SomeAPIFunction()
{
   try
   {
      // ...
      ErrorToException( SomeOtherAPIFunction() );
      // ...
      return OK;
   }
   catch (...)
   {
      return ExceptionToError();
   }
}

ErrorType ExceptionToError()
{
   try { throw; }
   catch(const Exception1 &) { return Error1; }
   catch(const Exception2 &) { return Error2; }
   ...
   catch(...) { return UnknownError; }
}

void ErrorToException(ErrorType error)
{
   switch (error)
   {
   case OK: return;
   case Error1: throw Exception1();
   case Error2: throw Exception2();
   ...
   default: throw UnknownException();
   }
}
Das ist immer noch alles andere als praktisch mit dem extra try-catch-Block in jeder API-Funktion. Da man bei goto aber genauso wenig um Labels oder alternativ Makros herumkommt, ist das zu verschmerzen, immerhin hat man so strukturierte und vollständige Fehlerbehandlung bei wohldefiniertem Programmablauf. Nur niemals den try-catch-Block vergessen. ;)
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Halan
Beiträge: 73
Registriert: 22.01.2005, 21:47
Benutzertext: programmiersüchtig
Echter Name: Kai Mast
Wohnort: Freak City
Kontaktdaten:

Re: [C++] constptr

Beitrag von Halan »

BeRsErKeR hat geschrieben:Ich frage mich ob Schreibaufwand eine Rechtfertigung für solch eine Implementierung ist, da du dir dadurch ja unnötigen Overhead einhandelst.
Deswegen habe ich den Thread hier eigentlich eröffnet um genau dazu Hilfe zu bekommen.

In c++11 gibt es ja Template aliases und sontiges neues. Frage mich ob das nicht mit sowas umzusetzen wäre.
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: [C++] constptr

Beitrag von CodingCat »

Ja, wäre es:

template <typename T>
using const_const_ptr = T const *const;


Aber macht es das wirklich besser? ;)
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
Schrompf
Moderator
Beiträge: 4864
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: [C++] constptr

Beitrag von Schrompf »

Wie benutzt man das dann? So?

Code: Alles auswählen

const_const_ptr<MeineKlasse> zeigerli;
Ich hätte sonst banal ein lokales typedef empfohlen:

Code: Alles auswählen

 class MeineKlasse 
{
public:
  typedef const MeineKlasse* const ConstPtr;
}
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: [C++] constptr

Beitrag von CodingCat »

Ja genau. In C++03 ginge das natürlich auch mit einer Hilfsstruktur:

Code: Alles auswählen

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

const_const_ptr_t<int>::type fooptr; // sehr hässlich ;-)
Aber ja, sollte ein Zeigertyp sehr oft vorkommen, ist ein einfaches typedef im jeweiligen Anwendungskontext mit Sicherheit die sinnvollste Lösung.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
Krishty
Establishment
Beiträge: 8257
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [C++] constptr

Beitrag von Krishty »

Bild
Wenn Leute const vor den Basistypen schreiben
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
eXile
Establishment
Beiträge: 1136
Registriert: 28.02.2009, 13:27

Re: [C++] constptr

Beitrag von eXile »

Krishty hat geschrieben:Wenn Leute const vor den Basistypen schreiben
Ich schreibe es auch nach den Typen, weil ich nicht in solchen Mist tappen will.
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: [C++] constptr

Beitrag von CodingCat »

Ich schreibe es aus Gewohnheit meist noch immer vor den Typen, obwohl ich es hasse, weil es so inkonsistent mit Zeiger-Modifiziern ist. Auch hier wäre es ein Segen gewesen, wenn die C++-Grammatik Modifizier sinnvollerweise von vorneherein nur hinter dem Typen erlaubt hätte. Konsequentes Umschreiben meines Textes mittels Regex oder Script traue ich mich nicht, dafür habe ich zu viele Template-Spielereien, die still und heimlich kaputt gehen könnten. Bleibt nur, es gleich richtig an die nächste Generation weiterzugeben. :-/
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
Schrompf
Moderator
Beiträge: 4864
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: [C++] constptr

Beitrag von Schrompf »

Ich mag das const vor dem Typen, und ich bin bockig und lass das auch so.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: [C++] constptr

Beitrag von BeRsErKeR »

eXile hat geschrieben:
Krishty hat geschrieben:Wenn Leute const vor den Basistypen schreiben
Ich schreibe es auch nach den Typen, weil ich nicht in solchen Mist tappen will.
Das ist aber wieder was ganz anderes. Wenn das const hinter char aber vor dem * steht hast du das gleiche Problem. Bei Pointern ist ja nur entscheidend, ob das const vor oder hinter dem * steht.


Ich denke der Grund warum viele das const nach vorn ziehen ist, weil man so halt liest: const int x -> konstanter Integer x. Was ich allerdings viel schlimmer finde ist die Tatsache, DASS man eine Wahl hat wo man das const hinschreibt. Ich finde C++ allgemein an einigen stellen zu un-strikt.
Ohne Input kein Output.
Benutzeravatar
Krishty
Establishment
Beiträge: 8257
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [C++] constptr

Beitrag von Krishty »

BeRsErKeR hat geschrieben:Ich denke der Grund warum viele das const nach vorn ziehen ist, weil man so halt liest: const int x -> konstanter Integer x.
Nein tut man nicht. C++-Typnamen werden grundsätzlich von hinten nach vorn gelesen:
int const * const * &
von hinten nach vorn:
& * const * const int
reference to | pointer to | constant pointer to | constant int.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [C++] constptr

Beitrag von dot »

Krishty hat geschrieben:
BeRsErKeR hat geschrieben:Ich denke der Grund warum viele das const nach vorn ziehen ist, weil man so halt liest: const int x -> konstanter Integer x.
Nein tut man nicht. C++-Typnamen werden grundsätzlich von hinten nach vorn gelesen: [...]
Nein tut man nicht. ;)

In C++ werden Deklarationen grundsätzlich von innen nach außen gelesen :P
Wenn man sich das mal klargemacht hat, dann ist die so oft kritisierte Syntax eigentlich ganz ok.

Abgesehen davon, ist es Geschmackssache. Ich persönlich bevorzuge auch, das vorderste const vorn hinzuschreiben.
Benutzeravatar
eXile
Establishment
Beiträge: 1136
Registriert: 28.02.2009, 13:27

Re: [C++] constptr

Beitrag von eXile »

BeRsErKeR hat geschrieben:Das ist aber wieder was ganz anderes. Wenn das const hinter char aber vor dem * steht hast du das gleiche Problem. Bei Pointern ist ja nur entscheidend, ob das const vor oder hinter dem * steht.
Ja natürlich; durch konsequente Von-rechts-nach-links-Notation (auch wenn dot es gerne anders hätte) hätte der Fehler trotzdem vermieden werden können, weil so offensichtlich wird, wo const dem Basistyp hinzugefügt wird.
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: [C++] constptr

Beitrag von BeRsErKeR »

Krishty hat geschrieben:
BeRsErKeR hat geschrieben:Ich denke der Grund warum viele das const nach vorn ziehen ist, weil man so halt liest: const int x -> konstanter Integer x.
Nein tut man nicht. C++-Typnamen werden grundsätzlich von hinten nach vorn gelesen:
int const * const * &
von hinten nach vorn:
& * const * const int
reference to | pointer to | constant pointer to | constant int.
Du hast mich falsch verstanden. Ich habe nicht davon geredet, wie man es in C++ korrekt liest, sondern wie man in der westlichen Welt üblicherweise Texte im allgemeinen liest. Und dieses Verhalten ist nun mal stärker in einem verwurzelt als die "korrekte" Reihenfolge in C++. Von Korrektheit habe ich überhaupt nicht gesprochen, sondern nur von Gewohnheit.
Ohne Input kein Output.
Benutzeravatar
mnemonix
Establishment
Beiträge: 101
Registriert: 09.04.2010, 20:38

Re: [C++] constptr

Beitrag von mnemonix »

Krass, man lernt hier auf ZFX immer was dazu zu C++ (natürlich auch in anderen Sachen). ;) Zumindest find ich das Argument von eXile recht stichhaltig (bzgl. Templates). Wäre eine Überlegung wert mal seinen Stil bzgl. const zu wechseln. Schreibe auch immer const vor den Typ, gewohnheitsgemäß. Hm, solche Sachen (Findings) zu C++ müssten evtl. mal in einem Extra-Thread oder Wiki festgehalten werden (ungefähr so wie in Scott Meyers' Büchern, natürlich nicht so ausführlich).
ftb
Beiträge: 6
Registriert: 13.06.2012, 00:30

Re: [C++] constptr

Beitrag von ftb »

Was ist denn jetzt so die Zusammenfassung von dem ganzen, was ist gut/was ist schlecht?
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [C++] constptr

Beitrag von dot »

Zusammenfassung: Es ist Geschmackssache.
ftb
Beiträge: 6
Registriert: 13.06.2012, 00:30

Re: [C++] constptr

Beitrag von ftb »

Kam mir jetzt nicht so vor als ob das unbedingt Geschmack wäre :p.
Benutzeravatar
Krishty
Establishment
Beiträge: 8257
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [C++] constptr

Beitrag von Krishty »

BeRsErKeR hat geschrieben:Du hast mich falsch verstanden. Ich habe nicht davon geredet, wie man es in C++ korrekt liest, sondern wie man in der westlichen Welt üblicherweise Texte im allgemeinen liest.
Ja; habe ich – entschuldige.

Übrigens ist mir erst jetzt klar geworden, dass die freie Wahl zwischen vorn und hinten durchaus vorteilhaft sein kann. So kommt man, wie in eXiles Beispiel, vom abgeleiteten Typ zum Basistyp zurück; ähnlich wie ein freies :: einen immer zum globalen Namespace zurückwirft. Dass es aber auch von Anfang an so geplant war, bezweifle ich. Okay; das war Quatsch. Danke, Cat.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Antworten