Muss ich eine public-bool-Variable initialisieren? [gelöst]
-
Hi Kolumbus,
hab mir gerade das Posting durchgelesen, das du nicht verstanden hast. Muss mich wohl beim Umformulieren des Satzes etwas, äh, verheddert haben. Manchmal eine Grammatik wie ein griechischer Gemüsehändler ich habe, junger Padawan.
Aber jetzt im Ernst:
Wenn die Konstruktion eines Objektes teuer im Sinne von zeitaufwändig ist, z.B. wenn langwierige Berechnungen zur Bestimmung von Daten durchgeführt werden müssen, dann kann eine zweistufige Konstruktion durch eine private init() Methode Sinn machen. Angenommen eine Klasse hat komplexe, langwierig zu bestimmende, aber auch triviale Eigenschaften. Wenn man die komplexen Daten nicht braucht, macht es keinen Sinn, sie bereits im Konstruktor zu bestimmen, sondern erst beim ersten Zugriff auf diese Daten. Dieses Beispiel sollte das ganz gut veranschaulichen:class ComplexObject { ComplexData Data_; unsigned int TrivialInt_; bool Initialized_; public: ComplexObject() : TrivialInt_( 1 ), // Integer mit 1 initialisieren Initialized_( false ) // komplexe Eigenschaft noch nicht initialisiert { } unsigned int get_int() const { // Zugriff auf triviale Eigenschaft return TrivialInt_; } ComplexData get_complex() const { // Zugriff auf komplexe Daten if( false == Initialized_ ) { // Daten werden zum ersten Mal angefragt, Bestimmung durchführen init(); } return Data_; } private: void init() { // führe Bestimmung der komplexen Eigenschaft durch // ... // Objekt jetzt vollständig initialisiert Initialized_ = true; } };
Das Ganze firmiert unter lazy initialization, glaube ich.
Gruß,
Doc
-
DocShoe schrieb:
Das Ganze firmiert unter lazy initialization, glaube ich.
Oder auch als Virtual-Proxy-Pattern.
-
Da fällt mir noch was auf:
Wofür werden die member ArrayA und ArrayB benutzt? std::vector bietet ungemein viele Vorteile gegenüber C-style arrays, insbesondere was das Überprüfen von gültigen Indizes oder die Übergabe an Funktionen betrifft.
Ich setze C-style Arrays nur noch dann ein, wenn folgende Kriterien zutreffen:
- ich benötige genau N Elemente
- die Benutzung des Arrays ist lokal, es wird niemals als Funktionsparamter benutztIn deinem Beispiel könnte man
class TestClass { unsigned char ArrayA[520]; unsigned char ArrayB[120]; public: TestClass() { memset( ArrayB, 0, 120 ); ArrayB[60] = 0xBB; } };
durch
class TestClass { std::vector<unsigned int> ArrayA; std::vector<unsigned int> ArrayB; public: TestClass() : ArrayA( 520 ), ArrayB( 120, 0 ) { ArrayB[60] = 0xBB; } };
ersetzen.
-
DocShoe schrieb:
[...] Muss mich wohl beim Umformulieren des Satzes etwas, äh, verheddert haben. Manchmal eine Grammatik wie ein griechischer Gemüsehändler ich habe, junger Padawan.
Wieder mal hat's den Kollegen gegenüber voll erwischt als ich losgeprustet habe...
Ich werd' mal ein Handtuch ins unterste Schreibtischfach legen, für alle Fälle.
Vielen Dank für die anschauliche Erklärung Doc, das leuchtet mir ein!
witte schrieb:
DocShoe schrieb:
Das Ganze firmiert unter lazy initialization, glaube ich.
Oder auch als Virtual-Proxy-Pattern.
Also "zwei-/mehrstufige Initialisierung" kann ich mir besser merken. "lazy initialization" ist ja wenigstens noch so ausgedrückt, dass es das Vorgehen etwas beschreibt, aber "Virtual-Proxy-Pattern" ist mir irgendwie viel zu abstrakt... Oder wie kann ich die Worte in Zusammenhang zu dem von Doc beschriebenen Vorgehen bringen?
-
O.K., von mir falsch ausgedrückt. Bei dem virtuellen Stellvertretermuster existieren zwei Klassen die denselben Typen implementieren. Die eine ist leicht und simuliert nur Basisfunktionalität, die andere die komplette.
Wenn Du jetzt teuer im Sinne von Rechenzeit meinst, nimm' den Ansatz von _DocShoe_. Wenn Du aber teuer im Sinne von Speicherverbrauch meinst dann nimm dieses Muster. Beispiel: Textdokument laden: Erstmal Platzhalter für die Bilder generieren damit das Layout stimmt (nur Eigenschaften Höhe und Breite), und die kompletten Teile erst dann laden, wenn der Benutzer zu den entsprechenden Seiten blättert.
-
Ahhh
klar witte, das Vorgehen ist natürlich von einem sehr ähnlichen Ansatz motiviert - verstehe! Also ist Virtual-Proxy-Pattern etwas Ähnliches, aber nicht dasselbe und deswegen konnte ich den Begriff nicht so richtig zuordnen. Alles klar.
DocShoe schrieb:
Da fällt mir noch was auf:
Wofür werden die member ArrayA und ArrayB benutzt? std::vector bietet ungemein viele Vorteile gegenüber C-style arrays, insbesondere was das Überprüfen von gültigen Indizes oder die Übergabe an Funktionen betrifft.
Ich setze C-style Arrays nur noch dann ein, wenn folgende Kriterien zutreffen:
- ich benötige genau N Elemente
- die Benutzung des Arrays ist lokal, es wird niemals als Funktionsparamter benutzt [...]Beides ist bei Beiden Arrays der Fall.
Trotzdem Danke für den Hinweis! Hast du absichtlich im std::vector-Beispiel unsigned int-Arrays genommen oder zufällig?
-
Ooops, Fehler meinerseits. Natürlich sollte das unsigned char heissen.
Gruß,
Doc
-
Hallo Gemeinschaft,
ich habe noch eine Frage zu der Initialisiererliste:
Wenn ich ein konstantes C-Style-Array im Header als private deklariere:
//*.h private: const unsigned char CArray[5];
wie und wo kann ich es dann initialisieren?
Im Moment habe ich es als globale Variable, was mir jedoch nicht gefällt:
//*.cpp const unsigned char CArray[5]= {0x01, 0x02, 0x03,0x04, 0x05};
MfG
-
Hallo
Wenn du die deklaration noch static machst ist das globale schon fast richtig, es fehlt nur noch der Klassenbezug wie bei Methoden
const unsigned char ClassName::CArray[5]= {0x01, 0x02, 0x03,0x04, 0x05};
Dann ist es eben nicht mehr global, sondern als Member implementiert.
Ansonsten must du es im Konstruktor mit Werten füllen, denn richtig initialisieren geht dann nicht.
bis bald
akari
-
Danke Dir!