Wie von mehreren Personen gesagt wurde, können Sie den Aufruf eines Basisklassenkonstruktors nicht verzögern, aber Konrad has given a good answer, der Ihr Problem gut lösen könnte. Dies hat jedoch seine Nachteile (z. B. wenn Sie mehrere Funktionen mit Werten initialisieren müssen, deren Berechnungen Zwischenergebnisse aufweisen). Um das Problem der festen Initialisierungsreihenfolge durch unter Verwendung von zu lösen, ist hier eine andere Möglichkeit .
Angesichts der festen Reihenfolge der Initialisierung, wenn Sie Kontrolle über die abgeleitete Klasse haben (und wie sonst würden Sie kommen, um mit einem seiner Ctors Geige?), Können Sie in einer privaten Basis schleichen, so dass es vor der anderen Basis wird initialisiert wird, die mit der privaten Basis bereits berechneten Werten kann dann initialisiert werden:
class my_dirty_little_secret {
// friend class the_class;
public:
my_dirty_little_secret(const std::string& str)
{
// however that calculates x, y, and z from str I wouldn't know
}
int x;
std::string y;
float z;
};
class the_class : private my_dirty_little_secret // must be first, see ctor
, public the_other_base_class {
public:
the_class(const std::string str)
: my_dirty_little_secret(str)
, the_other_base_class(x, y, z)
{
}
// ...
};
Die my_dirty_little_secret
Klasse ist so eine private Basis dass Benutzer von the_class
es nicht benutzen können, alle ihre Sachen sind auch privat, mit ausdrücklicher Freundschaft, die nur the_class
Zugang zu ihm gewährt. Da es jedoch zuerst in der Basisklassenliste aufgeführt wird, wird es zuverlässig vor the_other_base_class
erstellt, was auch immer es berechnet, kann verwendet werden, um das zu initialisieren.
Ein schöner Kommentar in der Basis-Klassenliste verhindert hoffentlich, dass andere Dinge durch Refactoring brechen.
Danke, dachte nicht darüber nach, nur eine Funktion aufzurufen, so dass es funktionieren wird, aber es wird ein bisschen unordentlich sein, weil der Konstruktor 2 Parameter hat. Ich werde diese Antwort akzeptieren, wenn ich kann (es sei denn, es kommt natürlich eine bessere heraus). Übrigens, du hast recht, dass du das nicht in Java und C# machen kannst, ich habe mir gesagt, dass es in Java möglich ist, weil es 'super (...)' im Methodenhauptteil verwendet hat, aber jetzt habe ich es bemerkt muss die erste Zeile sein. – placeholder
+1 Sie sollten some_function() statisch machen, um die Tatsache zu dokumentieren, dass keine Instanzvariablen der Klasse verwendet werden (die nicht initialisiert wurden). –
Interessant, noch nie zuvor gesehen. Ich nehme an, dass die aufgerufene Funktion eine abgeleitete Klassenfunktion sein kann. – PatrickV