Sprachmittel, die ihr nie benutzt
-
Aus Interesse wollte ich euch mal fragen, welche Sprachmittel ihr (praktisch) nie verwendet. Wichtig ist, dass ich mich hier nur auf C++98 und nicht auf Bibliotheksmittel beziehe. Gesamthaft existieren natürlich etliche Regeln im C++-Standard, von denen man kaum Gebrauch macht. Im Vordergrund sollen einigermassen bekannte und bewusst als Feature aufgefasste Möglichkeiten stehen.
Sprachmittel, die ich nie einsetze:
- Exception-Spezifikationen
- variable Argumentlisten
- Speicherklassen-Schlüsselwörter
registerundauto protected-Vererbung- Pointer-to-Member (nicht Memberfunktionszeiger)
- Function-Style- und C-Casts
- Bitfelder
- Digraphen, Trigraphen, alternative Schlüsselwörter (
andetc.) export
Sehr selten:
- virtuelle Vererbung
- eigene
new- unddelete-Operatoren - Funktionstemplate-Spezialisierung
const_cast,dynamic_castuniongotovolatile- Arrays
Gibt sicher noch mehr, die Listen kann ich ja noch ergänzen... Wie siehts bei euch aus?
-
[]variable Argumentlisten
[]Speicherklassen-Schlüsselwörterregisterundauto
[]protected-Vererbung
[]Pointer-to-Member (nicht Memberfunktionszeiger)
[]Function-Style- und C-Casts <-- wegen grep
[]Bitfelder
[]Digraphen, Trigraphen, alternative Schlüsselwörter (andetc.)
[]export[/list]Sehr selten:- virtuelle Vererbung
- eigene
new- unddelete-Operatoren uniongotovolatile- Arrays
Gibt sicher noch mehr, die Listen kann ich ja noch ergänzen...
[]vector<bool> <--- fiese bugs die jede menge zeit kosten
[]inline <--- mittlerweile sind compiler schlau genug es selber zu optimieren
[]unsigned statt unsgined int wg. auto int
[]Rückgabe von Roh Zeigern *
[*]Eigenes delete, dafür gibt es shared_ptr, unique_ptrUm
const_cast,dynamic_castkommt man leider nicht rum wenn man doppelten code in operatoren vermeiden möchte.
-
Bei mir wäre die Liste ein wenig länger - aber das könnte auch daran liegen, daß ich im täglichen Einsatz nichts mit C++ zu tun habe

Aber ansonsten fallen mir als kaum bis gar nicht genutzte Features noch Funktionszeiger, #define (außer für Include-Guards) und globale Variablen ein (letztere aus Prinzip und wegen der dadurch möglichen Nebeneffekte).
-
asdsad schrieb:
vector<bool> <--- fiese bugs die jede menge zeit kosten
Ist ein Bibliotheks- und kein Sprachmittel.
asdsad schrieb:
inline <--- mittlerweile sind compiler schlau genug es selber zu optimieren
Brauche ich nicht zur Optimierung, aber um Funktionen im Header definieren zu können (für Header-Only-Funktionalität)
asdsad schrieb:
Rückgabe von Roh Zeigern *
Brauche ich schon ab und zu. Ich sehe auch nichts, was dagegen spricht, wenn der Zeiger keinen Besitz überträgt.
asdsad schrieb:
Eigenes delete, dafür gibt es shared_ptr, unique_ptr
Ja,
deletebenutze ich im Anwendungscode auch recht wenig,delete[]noch viel weniger. Aber ich habe in letzter Zeit einige Low-Level-Dinge wie Smart-Pointer implementiert.asdsad schrieb:
Um
const_cast,dynamic_castkommt man leider nicht rum wenn man doppelten code in operatoren vermeiden möchte.dynamic_castbrauchst du dazu nicht. Und bei mir sind solche Operatoren wohl meist trivial genug gewesen, um Code zu duplizieren...
-
Wenn ich pur C++ programmiere, dann verwende ich selten...
- char* btw. char[] (stattdessen die string-Klasse)
- defines
- structs
- protected VererbungDa fallen mir noch ein dutzend mehr Dinge ein.

-
CStoll schrieb:
Funktionszeiger
Brauche ich oft – meist um sie gleich in eine
std::functionzu stecken, aber von Zeit zu Zeit werden sie auch direkt abgespeichert.CStoll schrieb:
#define (außer für Include-Guards)
Habe ich auch ab und zu. Nicht nur für Konfiguration und bedingte Kompilierung, sondern auch, um Boilerplate-Code wie Traits-Spezialisierungen anwenderfreundlich zu machen.
CStoll schrieb:
globale Variablen ein (letztere aus Prinzip und wegen der dadurch möglichen Nebeneffekte).
Konstanten habe ich manchmal, vor allem in .cpp-Dateien. Ich weiss nicht, ob du zu den Leuten gehörst, für die Konstanten keine Variablen sind

satanfreze schrieb:
- char* btw. char[]
Benutze ich für Stringliterale.
satanfreze schrieb:
- structs
Habe ich andauernd für Funktoren und kleine Hilfsklassen.
-
Nexus schrieb:
Brauche ich schon ab und zu. Ich sehe auch nichts, was dagegen spricht, wenn der Zeiger keinen Besitz überträgt.
const Objekt const * GetConstMember() const; ... Objekt * tmp = const_cast<Objekt *>(GetConstMember()); delete tmp; // Futsch ist der const Memberdynamic_cast<-- ist irgendwie dazwischengerutschtNexus schrieb:
Und bei mir sind solche Operatoren wohl meist trivial genug gewesen, um Code zu duplizieren...
Wenn man einen [] hat der einmal ein eine const memberfunktion und einmal zuordnung ist muss man zwangsläufig duplizieren oder const_casten.
-
Nexus schrieb:
CStoll schrieb:
globale Variablen ein (letztere aus Prinzip und wegen der dadurch möglichen Nebeneffekte).
Konstanten habe ich manchmal, vor allem in .cpp-Dateien. Ich weiss nicht, ob du zu den Leuten gehörst, für die Konstanten keine Variablen sind

globale Konstanten halte ich für unproblematisch, Variablen (in dem Sinn, daß sich ihr Wert ändern kann) führen schnell zu Spagetti-Code und endlosen Debugging-Sitzungen, weil du nicht einschränken kannst, wo sie tatsächlich genutzt und verändert werden (häufig an einer Stelle, die mit dem eigentlichen Problem gar nichts zu tun haben sollte).
-
asdsad schrieb:
Objekt * tmp = const_cast<Objekt *>(GetConstMember()); delete tmp; // Futsch ist der const MemberWer ohne zu denken
deleteauf Zeiger anwendet, nimmt die Probleme geradezu in Kauf. Als Bibliotheksentwickler kann man doch nicht auf solche Leute Rücksicht nehmen. Übrigens brauchst du dafür nicht malconst_cast.asdsad schrieb:
Wenn man einen [] hat der einmal ein eine const memberfunktion und einmal zuordnung ist muss man zwangsläufig duplizieren oder const_casten.
Lustig, jetzt habe ich tatsächlich gerade eine Codestelle entdeckt, wo ich etwa 5 Zeilen Code dupliziere, allerdings kein Operator. Könnte ich mir echt
const_castüberlegen
CStoll schrieb:
globale [...] Variablen [...] führen schnell zu Spagetti-Code und endlosen Debugging-Sitzungen
Völlig einverstanden

-
Nexus schrieb:
- Exception-Spezifikationen Ebenfalls nicht.
- variable Argumentlisten Nur für Meta-Programming.
- Speicherklassen-Schlüsselwörter
registerundautoEbenfalls nicht. protected-Vererbung Ebenfalls nicht.- Pointer-to-Member (nicht Memberfunktionszeiger) Ebenfalls nicht.
- Function-Style- und C-Casts Ebenfalls nicht.
- Bitfelder Extrem selten. Wenn ich mal bools packen möchte und Namen dazu haben will.
- Digraphen, Trigraphen, alternative Schlüsselwörter (
andetc.) Ebenfalls nicht. exportEbenfalls nicht.
Sehr selten:
- virtuelle Vererbung Gar nicht.
- eigene
new- unddelete-Operatoren Ebenfalls selten. - Funktionstemplate-Spezialisierung Das sagt mir jetzt nichts. Vermutlich erkenne ich's soofort, wenn ich's sehe.
const_cast,dynamic_castconst_cast noch nie, danymic_cast sehr selten.unionGelegentlich.gotoNie.volatileAnnähernd nie.- Arrays Für const char [], die zur Compilezeit bekannt sind. Ansonsten nicht.*
-
Wurde die Symmetrie des eingebauten Indexing Operators schon genannt?
Also dass
pointer[index]einfach zu*(pointer+index)wird, und man es daher auch alsindex[pointer]schreiben kann?Das ist nämlich auch was was ich nie verwende.
-
Interessanter wird es doch bei der Frage: Auf was könntet ihr verzichten? Also bei mir wären da nur Trigraphen, register, auto. Wobei auto von C++11 wohl eh eine neue Bedeutung bekommt.
-
hustbaer schrieb:
Wurde die Symmetrie des eingebauten Indexing Operators schon genannt?
Es ist eher die Symmetrie des eingebauten Plus-Operators.
-
Sprachmittel, die ich nie einsetze:
- Exception-Spezifikationen
- variable Argumentlisten
- Speicherklassen-Schlüsselwörter
registerundauto protected-Vererbung- Pointer-to-Member (nicht Memberfunktionszeiger)
- Bitfelder
- Digraphen, Trigraphen, alternative Schlüsselwörter (
andetc.) export- eigene
new- unddelete-Operatoren uniongotovolatile- Arrays
- C-String
Sprachmittel, die ich selten einsetze:
- Globale Variablen (und wenn auch nur für Objekt-Registrierung an anderen Klassen, oder Konstanten).
- #define (Nur für Headerguards und bedingte Compilierung, niemals für Konstanten und Funktionsersatz)
- delete (In der Regel ziehe ich Smartpointer wie scoped_ptr/unique_ptr & Co vor).
-
volkard schrieb:
hustbaer schrieb:
Wurde die Symmetrie des eingebauten Indexing Operators schon genannt?
Es ist eher die Symmetrie des eingebauten Plus-Operators.
Hihi, OK.
Dann eben dass der Indexing-Operator auf*(a+b)abgebildet wird.
Und Symmetrie ist sicher auch der falsche Ausdruck, aber ich glaube ihr versteht was ich meine.
-
hustbaer schrieb:
volkard schrieb:
hustbaer schrieb:
Wurde die Symmetrie des eingebauten Indexing Operators schon genannt?
Es ist eher die Symmetrie des eingebauten Plus-Operators.
Hihi, OK.
Dann eben dass der Indexing-Operator auf*(a+b)abgebildet wird.Das ist soweit eigentlich OK, es ist wirklich die Kommutativität von +, die nicht immer sinnvoll ist.
-
Bashar schrieb:
Das ist soweit eigentlich OK, es ist wirklich die Kommutativität von +, die nicht immer sinnvoll ist.
Wo sonst? Und findest du die Nicht-Kommutativität bei
std::stringsinnvoll?
-
Nexus schrieb:
Bashar schrieb:
Das ist soweit eigentlich OK, es ist wirklich die Kommutativität von +, die nicht immer sinnvoll ist.
Wo sonst? Und findest du die Nicht-Kommutativität bei
std::stringsinnvoll?Da war die Wahl de Zeichens '+' eine unglückliche Wahl.
-
Nexus schrieb:
Bashar schrieb:
Das ist soweit eigentlich OK, es ist wirklich die Kommutativität von +, die nicht immer sinnvoll ist.
Wo sonst? Und findest du die Nicht-Kommutativität bei
std::stringsinnvoll?Ja klar, warum nicht?
-
volkard schrieb:
Nexus schrieb:
Wo sonst? Und findest du die Nicht-Kommutativität bei
std::stringsinnvoll?Da war die Wahl de Zeichens '+' eine unglückliche Wahl.
Das ist Geschmackssache, ich finde es jedenfalls durchaus intuitiv bei der Anwendung.
-
asc schrieb:
Das ist Geschmackssache, ich finde es jedenfalls durchaus intuitiv bei der Anwendung.
Ich finde . und & auch nicht schlecht, in Basic-Dialekten, wo + und & gehen, bevorzuge ich &.