Seite 1 von 1

[C++] constptr

Verfasst: 12.06.2012, 13:50
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

Re: [C++] constptr

Verfasst: 12.06.2012, 15:46
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.

Re: [C++] constptr

Verfasst: 12.06.2012, 15:51
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.

Re: [C++] constptr

Verfasst: 12.06.2012, 16:31
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.

Re: [C++] constptr

Verfasst: 12.06.2012, 17:21
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...

Re: [C++] constptr

Verfasst: 12.06.2012, 17:33
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. ;)

Re: [C++] constptr

Verfasst: 12.06.2012, 21:09
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.

Re: [C++] constptr

Verfasst: 12.06.2012, 21:43
von CodingCat
Ja, wäre es:

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


Aber macht es das wirklich besser? ;)

Re: [C++] constptr

Verfasst: 12.06.2012, 21:48
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;
}

Re: [C++] constptr

Verfasst: 12.06.2012, 21:53
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.

Re: [C++] constptr

Verfasst: 12.06.2012, 22:28
von Krishty
Bild
Wenn Leute const vor den Basistypen schreiben

Re: [C++] constptr

Verfasst: 12.06.2012, 23:27
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.

Re: [C++] constptr

Verfasst: 12.06.2012, 23:50
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. :-/

Re: [C++] constptr

Verfasst: 13.06.2012, 00:10
von Schrompf
Ich mag das const vor dem Typen, und ich bin bockig und lass das auch so.

Re: [C++] constptr

Verfasst: 13.06.2012, 01:02
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.

Re: [C++] constptr

Verfasst: 13.06.2012, 05:52
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.

Re: [C++] constptr

Verfasst: 13.06.2012, 07:10
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.

Re: [C++] constptr

Verfasst: 13.06.2012, 11:33
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.

Re: [C++] constptr

Verfasst: 13.06.2012, 15:33
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.

Re: [C++] constptr

Verfasst: 13.06.2012, 18:49
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).

Re: [C++] constptr

Verfasst: 13.06.2012, 19:27
von ftb
Was ist denn jetzt so die Zusammenfassung von dem ganzen, was ist gut/was ist schlecht?

Re: [C++] constptr

Verfasst: 13.06.2012, 23:08
von dot
Zusammenfassung: Es ist Geschmackssache.

Re: [C++] constptr

Verfasst: 14.06.2012, 00:29
von ftb
Kam mir jetzt nicht so vor als ob das unbedingt Geschmack wäre :p.

Re: [C++] constptr

Verfasst: 16.06.2012, 11:28
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.