Eine
Konvertierung kann auch dann implizit durchgeführt werden, wenn der Weg über
mehrere Stufen geht. Allerdings ist dabei nur eine benutzerdefinierte Konvertierung sowie eine Standardkonvertierung erlaubt, was die Anzahl der möglichen
Stufen auf zwei begrenzt. Existieren mehrere Wege für eine Konvertierung, wird
der kürzeste bevorzugt. Darüber hinaus hat eine Standardkonvertierung Vorrang
gegenüber einer benutzerdefinierten Konvertierung.
Gibt es mehrere gleichwertige Wege, ist die Konvertierung mehrdeutig und damit
syntaktisch falsch.
Zur Demonstration rüsten wir die Klassen A und B wie folgt auf:
struct A
{
A( int ); //
Konstruktor #1 für A
/* ... weitere Mitglieder
von A */
};
struct B
{
B( char*
); // Konstruktor #1 für B
B( const
A& ); // Konstruktor #2 für B
operator
char*() const; // operator #1 für
B
/* ... weitere Mitglieder
von B */
};
Nun sind in einem Schritt z.B. folgende Konvertierungen möglich:
void f( const
A& );
void f( const
B& );
f( 32 );
//-- Konvertierung int
-> A mit Konstruktor #1 von A
f("Ein String" ); //--
Konvertierung char* -> B mit Konstruktor #1 von B
Folgendes Programmsegment zeigt eine Konvertierungen mit zwei Schritten:
void g( const
A& );
g( 'a' ); //
Konvertierung char -> int -> A
Bereits hier beginnt die Konstruktion unübersichtlich zu werden. Zunächst
wird der Wert a
(Typ char)
in ein temporäres Objekt vom Typ int
gewandelt, das dann wiederum als Argument an den Konstruktor #1 von A übergeben
wird, um ein weiteres temporäres Objekt zu erzeugen, auf das dann schließlich
eine Referenz an g
übergeben wird. In diesem Beispiel werden also sogar zwei temporäre Objekte benötigt.
Beachten Sie bitte, dass diese mehrstufige Konvertierung implizit ablaufen
kann, da nur eine Standardkonvertierung und eine benutzerdefinierte Konvertierung
erforderlich sind.
Diese Konstruktion ist dagegen nicht möglich:
void g( const
B& );
g( 5 ); //
Fehler!
Es gibt zwar einen Konvertierungsweg von int nach B, dieser erfordert jedoch
drei Schritte (int
=> A
=> B)
und ist daher unzulässig.