Objektreihenfolge
-
Warum meldet der Compiler hier keinen Fehler? Mit welchen Tools kann man solche Fehler erkennen?
/* http://www.gotw.ca/gotw/080.htm */ #include <iostream> #include <string> using namespace std; class A { public: A( const string& s ) {} string f() { return "hello, world"; } }; class B : public A { public: B() : A( s = f() ) {} //use of objects before they exist!!! string getString() { return s; } private: string s; }; int main() { B b; cout << b.getString(); // wird nichts ausgegeben! }
-
da is nur mangelndes sprachverständnis
B() : A( s = f() ) {}
in der zeile initialisierst du das argument 1 des ctors von A, hat also mit dem string s aus B nix zu tun.
aber mit
B() :s(f()){}
gibt er was aus, vorausgesetzt, der default ctor von A existiert.
klar, es kann sehr sehr gefährlich sein, dass so zu machen, aber im endeffekt liegts in der hand des programmierers,ob er zb eine private methode zum initialisieren der variable benutzt.
-
da is nur mangelndes sprachverständnis
B() : A( s = f() ) {}
in der zeile initialisierst du das argument 1 des ctors von A, hat also mit dem string s aus B nix zu tun.
Es hat doch was mit dem string s aus B zu tun. Dise Zeile hat jedoch zwei Fehler, da s = f() ausgeführt wird bevor der Konstruktor von A aufgerufen wird.
1. Es wird f() des Subobjektes A aufgerufen, obwohl dieses noch nicht konstruiert wurde. Bei nichttrivialen Funktionen ist eine Segmentation Violation sehr wahrscheinlich.
2. Es wird der string Zuweisungsoperator von s aufgerufen, obwohl s noch nicht konstruiert wurde. Dies gibt höchstwahrscheinlich eine Segmentation Violation, da ein string versuchen wird erst den alten String freizugeben, der zufällig grad in seinem Speicher liegt.
Man muß nicht viel Glück haben, damit dieser Code zu einer Segmentation Violation führt. In diesem Fall ist valgrind das Tool der Wahl um diesen Fehler schnell zu finden.
Allerdings sollte man sich angewöhnen solche Konstrukte nicht in der Initialisierungsliste zu verwenden.