In C ++ wurden die Initialisierer im C-Stil durch Konstruktoren ersetzt, die durch die Kompilierungszeit sicherstellen können, dass nur gültige Initialisierungen durchgeführt werden (dh nach der Initialisierung sind die Objektelemente konsistent).
Es ist eine gute Vorgehensweise, aber manchmal ist eine Vorinitialisierung praktisch, wie in Ihrem Beispiel. OOP löst dies durch abstrakte Klassen oder kreative Designmuster .
Meiner Meinung nach macht die Verwendung dieser sicheren Methode die Einfachheit zunichte und manchmal ist der Kompromiss zwischen Sicherheit zu teuer, da einfacher Code kein ausgeklügeltes Design benötigt, um wartbar zu bleiben.
Als alternative Lösung schlage ich vor, Makros mit Lambdas zu definieren, um die Initialisierung so zu vereinfachen, dass sie fast wie im C-Stil aussieht:
struct address {
int street_no;
const char *street_name;
const char *city;
const char *prov;
const char *postal_code;
};
#define ADDRESS_OPEN [] { address _={};
#define ADDRESS_CLOSE ; return _; }()
#define ADDRESS(x) ADDRESS_OPEN x ADDRESS_CLOSE
Das ADDRESS-Makro wird auf erweitert
[] { address _={}; /* definition... */ ; return _; }()
das schafft und nennt das Lambda. Makroparameter werden ebenfalls durch Kommas getrennt, sodass Sie den Initialisierer in Klammern setzen und wie aufrufen müssen
address temp_address = ADDRESS(( _.city = "Hamilton", _.prov = "Ontario" ));
Sie können auch einen verallgemeinerten Makroinitialisierer schreiben
#define INIT_OPEN(type) [] { type _={};
#define INIT_CLOSE ; return _; }()
#define INIT(type,x) INIT_OPEN(type) x INIT_CLOSE
aber dann ist der Anruf etwas weniger schön
address temp_address = INIT(address,( _.city = "Hamilton", _.prov = "Ontario" ));
Sie können das ADDRESS-Makro jedoch einfach mit dem allgemeinen INIT-Makro definieren
#define ADDRESS(x) INIT(address,x)