Ein weiterer Versuch:
Dies wird jämmerlich fehlschlagen, da const_val intern einen char * m_val beinhaltet. Die Initialisierung von USER_NAME aus einem Properties-Objekt kopiert einen nullterminierten String zu m_val. m_val ist jedoch NULL und eine Zugriffsverletzung trifft ein. m_val muss Speicher zugewiesen werden, der bei der Destruktion von const_val gelöscht werden sollte.
Eine Methode besteht darin, intern std::string beizubehalten und nach außen hin eine const char*-Umwandlung zu bieten. Genau das wird auch getan: Bei rohen char* Strings behält man intern std::strings bei. Hier erfordert die Lösung Traits, die den Klassen entsprechend erweitert werden können.
In den vorhergehenden Lösungen sorgten dependent_statics dafür, dass die Initialisierung statischer Variablen aufgeschoben wurde. Die Variable dependent_statics wird automatisch beim Aufruf von constants_and_dependents::initialize() initialisiert. Eine dependent_static muss jedoch nicht global sein. Der in Listing L gezeigte Code wird fehlschlagen.
Dagegen können const_val Konstanten nur global sein. Soll eine konstante Variable nur für eine Funktion gelten, ist const_val nicht erforderlich. Die Initialisierung einer lokalen Variable sollte nicht aufgeschoben, sondern umgehend stattfinden, und zwar mit get_prop_val:
Das war’s denn schon. Die endgültige Lösung ist in Listing M zu finden.
Weiterführende Themen
Wandelt man eine globale/statische Variable in dependent_static um, hat man normalerweise keine Probleme. Es gibt jedoch ein paar Situationen, in denen der Übergang nicht gar so unkompliziert ist:
Der Grund hierfür ist, dass dependent_static alle Parameter als Wert übernimmt. Will man eine Referenz übergeben, sollte eine Referenzklasse wie boost::ref/cref verwendet werden.
Wenn man ein Objekt übergeben will, dessen Klasse keinen Kopierkonstruktor hat, tritt ein Kompilierzeitfehler auf. Deshalb sollte das Objekt als Referenz übergeben werden. Möchte man eine const_val oder eine andere dependent_static übergeben, sollte man daran denken, dass diese nicht kopiert werden können, weswegen sie als Referenz übergeben werden müssen. Listing N zeigt Beispiele jeder Referenzübergabe.
Fazit
Der Wechsel zwischen Kompilierzeit- und Laufzeit-Konstanten sollte eigentlich einfach sein, ist es aber bei weitem nicht. Aus diesem Grund wurde hier die Kombination const_val und dependent_static entwickelt, was die Sache wesentlich einfacher macht. Noch ein letzter Hinweis: Laufzeit-Konstanten sollten immer zuerst Defaultwerte vergeben werden. Anschließend sind so viele Konstanten wie nur möglich von Kompilierzeit- in Laufzeit-Konstanten umzuwandeln. Auf diese Weise erhält man mehrere Sets von Konstanten, die zur Laufzeit zur Auswahl stehen, wodurch das Austesten/Debuggen/Profiling der Anwendung vereinfacht wird.
Mit dem Dekryptor von Bitdefender können Opfer von Attacken mit der Shrinklocker-Ransomware Dateien wiederherstellen.
In der Vorweihnachtszeit ist vor allem Malvertising auf dem Vormarsch. Cyberkriminelle locken Nutzer über schädliche…
Dazu trägt unter der Infostealer Lumma-Stealer bei. Hierzulande dominiert der Infostealer Formbook die Malware-Landschaft.
Eine schwerwiegende Anfälligkeit hebelt die Sicherheitsfunktion Seitenisolierung auf. Betroffen sind Chrome für Windows, macOS und…
DeepL Voice ermöglicht Live‑Übersetzung von Meetings und Gesprächen in 13 Sprachen.
Betroffen sind Windows und Windows Server. Microsoft patcht aber auch Schwachstellen in Excel, Word und…