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?
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

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.