Umwandlung von Kompilierzeit-Konstanten zu Laufzeit-Konstanten und umgekehrt

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< type> um, hat man normalerweise keine Probleme. Es gibt jedoch ein paar Situationen, in denen der Übergang nicht gar so unkompliziert ist:

  • Bei der Übergabe einer Referenz an ein Objekt
  • Bei der Übergabe eines Objekts, dessen Klasse keinen Kopierkonstruktur hat
  • Bei der Übergabe von const_val oder einer anderen dependent_static

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.

Themenseiten: Anwendungsentwicklung, Software

Fanden Sie diesen Artikel nützlich?
Content Loading ...
Whitepaper

Artikel empfehlen:

Neueste Kommentare 

Noch keine Kommentare zu Umwandlung von Kompilierzeit-Konstanten zu Laufzeit-Konstanten und umgekehrt

Kommentar hinzufügen

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *