Diese Frage besteht im Wesentlichen aus zwei Teilen: Speichern von Konfigurationswerten in einer einzigen Datei/Stelle und Verzögern der Initialisierung eines enthaltenen Objekts.Gesamtkonfigurationsobjekt für ein Gott-Objekt und späte Initialisierung
Speicher von Konfigurationswerten
Ich habe ein eingebettetes Programm, das eine Leiterplattentestvorrichtung für einen halbautomatischen Test steuert. Ich möchte alle Grenzwerte/Testparameter an einem einzigen Ort speichern (vorzugsweise als Read-Only/Konstanten), damit sie in der Zukunft einfach gefunden und optimiert werden können. Das Problem ist, dass einige der Werte in verschachtelten Strukturen liegen und die einzige Möglichkeit, diese Objekte zu initialisieren, ist die gefürchtete Initialisierungsliste, in der die Rückverfolgbarkeit verloren geht (oder ein Konstruktor, der fast genauso schlecht ist).
z.B.
class Configuration {
public:
struct NestedStruct {
float value1;
float value2;
float value3;
};
struct ContainerStruct {
int value1;
float value2;
NestedStruct nested1;
NestedStruct nested2;
NestedStruct nested3;
float value3;
};
// Initialise struct data member.
// Not obvious which value is which?
constexpr static const ContainerStruct containerStruct {5, 2.3, 1.4, 4.2, 0.7, 3.5, 2.5, 3.5, 0.2, 0.2, 0.1, 4.6};
// Slightly more readable
constexpr static const ContainerStruct containerStruct {5, 2.3, {1.4, 4.2, 0.7}, {3.5, 2.5, 3.5}, {0.2, 0.2, 0.1}, 4.6};
};
Wie können wir lesen speichern nur Konfigurationswerte aus den komplexen/verschachtelter Struktur Werte an einem Ort, während der Lesbarkeit beibehalten?
Controller/god Objekt Initialisierung
Ich habe beschlossen, die Kernfunktionalität in einem einzigen Controller-Objekt zu wickeln, das mehrere Objekte enthalten instanziiert. Eines dieser Objekte wird über einen Zeiger an einige der anderen Objekte übergeben. Ich verwende die oben genannten Konfigurationswerte (für die es viele gibt!), Um diese Objekte zu initialisieren.
Die Verwendung einer Initialisierungsliste macht den Konstruktor der Controller-Klasse lang und unordentlich. Eine Möglichkeit, dies zu umgehen, besteht darin, einen leeren Konstruktor für die enthaltenen Objekte mit einer separaten Initialisierungsfunktion zu erstellen, die ich im Rumpf des Konstruktors der Steuerung aufrufen könnte.
Allerdings habe ich immer gelesen, dass zwei Schritt/Lazy-Initialisierung ist schlecht, da das Objekt nicht sofort verwendbar ist. Gibt es einen anderen Weg?
Vielleicht gibt es einen besseren Weg, als es in ein Gott-Objekt zu wickeln?
Beispiel Parameter, die ich an einem Ort gespeichert werden sollen:
Adc Objektparameter:
float voltageReference;
uint8_t slaveSelectPin;
Navigationobjektparameter:
struct AdcValues {
uint_fast16_t buttonUp;
uint_fast16_t buttonDown;
uint_fast16_t buttonLeft;
uint_fast16_t buttonRight;
uint_fast16_t buttonCentre;
uint_fast8_t tolerance;
};
UutPower Objektparameter:
struct CurrentCompensation {
float LowX;
float LowC;
float MidX;
float MidC;
float HighX;
float HighC;
};
VoltageTests Objektparameter:
struct TestParameter {
float scalingFactor; // Potential divider scaling for voltages >voltageRef.
float limitLower;
float limitUpper;
const char *signalName;
};
// Lots of nested structs.
struct TestParameters {
TestParameter tb1_1;
TestParameter tp15;
TestParameter tp4;
TestParameter tp1;
TestParameter tp3;
TestParameter tp20;
TestParameter tp12;
TestParameter tp29;
TestParameter tp28;
TestParameter con3_6;
TestParameter con3_2;
}
Weitere Parameter:
float currentLimitLow;
float currentLimitHigh;
const char *version;
Jede Hilfe sehr geschätzt.
Ist C eine Option? In C könnten Sie designierte Initialisierer verwenden 'constexpr static const ContainerStruct containerStruct = {.value1 = 5}'. – Lundin
Es verwendet einen Arduino mit eingeschränkter Funktionalität von C++ - Standardbibliotheken (C mit Klassen, die ich vermute). Leider akzeptiert der Compiler das nicht, auch nicht den anderen Standard mit einem Doppelpunkt 'containerStruct = {value1: 5}' –
Ich hatte einmal eine sehr ähnliche Situation in einem Projekt. Eingebettete sys/Mikrocontroller, riesige Menge an Daten in Flash Eeprom (64kb), alles in einer großen Monster-Struktur. Es ist immer noch ziemlich gut geworden, weil ich bestimmte Initialisierer verwenden konnte. Ohne sie wäre es ziemlich hässlich geworden. Eine der wenigen Anwendungen, die ich für designierte Initialisierer gefunden habe. – Lundin