FunktionsüberladungFunction Overloading

C++ lässt die Angabe mehrerer Funktionen mit dem gleichen Namen im gleichen Gültigkeitsbereich zu.C++ allows specification of more than one function of the same name in the same scope. Diese Funktionen werden als überladene Funktionen bezeichnet.These functions are called overloaded functions. Überladene Funktionen ermöglichen es Ihnen, abhängig von den Typen und der Anzahl der Argumente unterschiedliche Semantik für eine Funktion bereitzustellen.Overloaded functions enable you to supply different semantics for a function, depending on the types and number of arguments.

Beispielsweise kann eine print Funktion, die ein-Argument annimmt, std::string sehr unterschiedliche Aufgaben ausführen als eine, die ein Argument vom Typ annimmt double .For example, a print function that takes a std::string argument might perform very different tasks than one that takes an argument of type double. Durch das überladen müssen Sie keine Namen wie oder verwenden print_string print_double .Overloading saves you from having to use names such as print_string or print_double. Zum Zeitpunkt der Kompilierung wählt der Compiler basierend auf dem Typ der vom Aufrufer übergebenen Argumente aus, welche Überladung verwendet werden soll.At compile time, the compiler chooses which overload to use based on the type of arguments passed in by the caller. Wenn Sie aufrufen print(42.0) , wird die- void print(double d) Funktion aufgerufen.If you call print(42.0), then the void print(double d) function will be invoked. Wenn Sie aufrufen print("hello world") , wird die Überladung void print(std::string) aufgerufen.If you call print("hello world"), then the void print(std::string) overload will be invoked.

Sie können sowohl Element Funktionen als auch nicht-Member-Funktionen überladen.You can overload both member functions and non-member functions. Die folgende Tabelle zeigt, welche Teile einer Funktionsdeklaration von C++ verwendet werden, um zwischen Gruppen von Funktionen mit dem gleichen Namen und dem gleichen Gültigkeitsbereich zu differenzieren.The following table shows what parts of a function declaration C++ uses to differentiate between groups of functions with the same name in the same scope.

Überlegungen zur ÜberladungOverloading Considerations

FunktionsdeklarationselementFunction Declaration Element Wird zum Überladen verwendet?Used for Overloading?
FunktionsrückgabetypFunction return type NeinNo
Anzahl der ArgumenteNumber of arguments JaYes
Typ der ArgumenteType of arguments JaYes
Vorhandensein oder Abwesenheit von AuslassungszeichenPresence or absence of ellipsis JaYes
Verwendung von typedef NamenUse of typedef names NeinNo
Nicht angegebene ArraygrenzenUnspecified array bounds NeinNo
const oder volatileconst or volatile Ja, wenn auf die gesamte Funktion angewendetYes, when applied to entire function
Ref-QualifiziererRef-qualifiers JaYes

BeispielExample

Das folgende Beispiel veranschaulicht, wie das Überladen verwendet werden kann.The following example illustrates how overloading can be used.

// function_overloading.cpp
// compile with: /EHsc
#include <iostream>
#include <math.h>
#include <string>

// Prototype three print functions.
int print(std::string s);             // Print a string.
int print(double dvalue);            // Print a double.
int print(double dvalue, int prec);  // Print a double with a
                                     //  given precision.
using namespace std;
int main(int argc, char *argv[])
{
    const double d = 893094.2987;
    if (argc < 2)
    {
        // These calls to print invoke print( char *s ).
        print("This program requires one argument.");
        print("The argument specifies the number of");
        print("digits precision for the second number");
        print("printed.");
        exit(0);
    }

    // Invoke print( double dvalue ).
    print(d);

    // Invoke print( double dvalue, int prec ).
    print(d, atoi(argv[1]));
}

// Print a string.
int print(string s)
{
    cout << s << endl;
    return cout.good();
}

// Print a double in default precision.
int print(double dvalue)
{
    cout << dvalue << endl;
    return cout.good();
}

//  Print a double in specified precision.
//  Positive numbers for precision indicate how many digits
//  precision after the decimal point to show. Negative
//  numbers for precision indicate where to round the number
//  to the left of the decimal point.
int print(double dvalue, int prec)
{
    // Use table-lookup for rounding/truncation.
    static const double rgPow10[] = {
        10E-7, 10E-6, 10E-5, 10E-4, 10E-3, 10E-2, 10E-1,
        10E0, 10E1,  10E2,  10E3,  10E4, 10E5,  10E6 };
    const int iPowZero = 6;

    // If precision out of range, just print the number.
    if (prec < -6 || prec > 7)
    {
        return print(dvalue);
    }
    // Scale, truncate, then rescale.
    dvalue = floor(dvalue / rgPow10[iPowZero - prec]) *
        rgPow10[iPowZero - prec];
    cout << dvalue << endl;
    return cout.good();
}

Der vorhergehende Code zeigt das Überladen der print-Funktion im Dateigültigkeitsbereich an.The preceding code shows overloading of the print function in file scope.

Das default-Argument wird nicht als Teil des Funktions Typs behandelt.The default argument isn't considered part of the function type. Daher wird Sie nicht bei der Auswahl überladener Funktionen verwendet.Therefore, it's not used in selecting overloaded functions. Zwei Funktionen, die sich nur bei den Standardargumenten unterscheiden, werden als mehrfache Definitionen und nicht als überladene Funktionen betrachtet.Two functions that differ only in their default arguments are considered multiple definitions rather than overloaded functions.

Für überladene Operatoren können keine Standardargumente angegeben werden.Default arguments can't be supplied for overloaded operators.

ArgumentübereinstimmungArgument Matching

Überladene Funktionen werden für die beste Übereinstimmung von Funktionsdeklarationen im aktuellen Bereich für Argumente ausgewählt, die im Funktionsaufruf angegeben werden.Overloaded functions are selected for the best match of function declarations in the current scope to the arguments supplied in the function call. Wenn eine passende Funktion gefunden wird, wird diese Funktion aufgerufen.If a suitable function is found, that function is called. "Passend" in diesem Kontext bedeutet Folgendes:"Suitable" in this context means either:

  • Ein exakte Übereinstimmung wurde gefunden.An exact match was found.

  • Eine triviale Konvertierung wurde ausgeführt.A trivial conversion was performed.

  • Eine ganzzahlige Heraufstufung wurde ausgeführt.An integral promotion was performed.

  • Eine Standardkonvertierung zum gewünschten Argumenttyp ist vorhanden.A standard conversion to the desired argument type exists.

  • Eine benutzerdefinierte Konvertierung (entweder Konvertierungsoperator oder Konstruktor) auf den gewünschten Argumenttyp ist vorhanden.A user-defined conversion (either conversion operator or constructor) to the desired argument type exists.

  • Es wurden durch Ellipsen dargestellte Argumente gefunden.Arguments represented by an ellipsis were found.

Der Compiler erstellt einen Satz Kandidatenfunktionen für jedes Argument.The compiler creates a set of candidate functions for each argument. Kandidatenfunktionen sind Funktionen, in denen das tatsächliche Argument an dieser Position in den Typ des formalen Arguments konvertiert werden kann.Candidate functions are functions in which the actual argument in that position can be converted to the type of the formal argument.

Ein Satz von „am besten passenden Funktionen“ wird für jedes Argument erstellt, und die ausgewählte Funktion ist die Schnittmenge aller Sätze.A set of "best matching functions" is built for each argument, and the selected function is the intersection of all the sets. Wenn die Schnittmenge mehr als eine Funktion enthält, ist das Überladen mehrdeutig und generiert einen Fehler.If the intersection contains more than one function, the overloading is ambiguous and generates an error. Die letztendlich ausgewählte Funktion stimmt stets besser überein als jede andere Funktion in der Gruppe für mindestens ein Argument.The function that is eventually selected is always a better match than every other function in the group for at least one argument. Wenn kein klarer Gewinner vorhanden ist, generiert der Funktionsaufruf einen Fehler.If there's no clear winner, the function call generates an error.

Berücksichtigen Sie die folgenden Deklarationen (Funktionen sind zur Identifikation der folgenden Erläuterung als Variant 1, Variant 2 und Variant 3 gekennzeichnet):Consider the following declarations (the functions are marked Variant 1, Variant 2, and Variant 3, for identification in the following discussion):

Fraction &Add( Fraction &f, long l );       // Variant 1
Fraction &Add( long l, Fraction &f );       // Variant 2
Fraction &Add( Fraction &f, Fraction &f );  // Variant 3

Fraction F1, F2;

Betrachten Sie folgende Anweisung:Consider the following statement:

F1 = Add( F2, 23 );

Die vorhergehende Anweisung erstellt zwei Sätze:The preceding statement builds two sets:

Satz 1: Kandidatenfunktionen, deren erstes Argument vom Typ „fraction“ istSet 1: Candidate Functions That Have First Argument of Type Fraction Menge 2: Kandidaten Funktionen, deren zweites Argument in den Typ konvertiert werden kann intSet 2: Candidate Functions Whose Second Argument Can Be Converted to Type int
Variant 1Variant 1 Variante 1 ( int kann in long mithilfe einer Standard Konvertierung konvertiert werden)Variant 1 (int can be converted to long using a standard conversion)
Variant 3Variant 3

Funktionen in Set 2 sind Funktionen, für die implizite Konvertierungen von tatsächlichem Parametertyp in formalen Parametertyp vorhanden sind, und unter diesen Funktionen gibt es eine Funktion, für die die "Kosten" der Konvertierung des tatsächlichen Parameter Typs in den formalen Parametertyp der kleinste Wert ist.Functions in Set 2 are functions for which there are implicit conversions from actual parameter type to formal parameter type, and among such functions there's a function for which the "cost" of converting the actual parameter type to its formal parameter type is the smallest.

Die Schnittmenge dieser beiden Sätze ist "Variant 1".The intersection of these two sets is Variant 1. Ein Beispiel für einen mehrdeutigen Funktionsaufruf ist:An example of an ambiguous function call is:

F1 = Add( 3, 6 );

Der vorhergehende Funktionsaufruf erstellt die folgenden Sätze:The preceding function call builds the following sets:

Set 1: Kandidaten Funktionen, die ein erstes Argument vom Typ aufweisen intSet 1: Candidate Functions That Have First Argument of Type int Menge 2: Kandidaten Funktionen, die ein zweites Argument vom Typ aufweisen intSet 2: Candidate Functions That Have Second Argument of Type int
Variante 2 ( int kann in long mithilfe einer Standard Konvertierung konvertiert werden)Variant 2 (int can be converted to long using a standard conversion) Variante 1 ( int kann in long mithilfe einer Standard Konvertierung konvertiert werden)Variant 1 (int can be converted to long using a standard conversion)

Da die Schnittmenge dieser beiden Sätze leer ist, generiert der Compiler eine Fehlermeldung.Because the intersection of these two sets is empty, the compiler generates an error message.

Bei einem Argument Abgleich wird eine Funktion mit n -Standardargumenten als n+ 1 separate Funktionen behandelt, von denen jede eine andere Anzahl von Argumenten hat.For argument matching, a function with n default arguments is treated as n+1 separate functions, each with a different number of arguments.

Die Ellipse (...) dient als Platzhalter; sie stimmt mit jedem tatsächlichen Argument überein.The ellipsis (...) acts as a wildcard; it matches any actual argument. Dies kann zu vielen mehrdeutigen Sätzen führen, wenn Sie die überladenen Funktions Sätze nicht mit äußerster Sorgfalt entwerfen.It can lead to many ambiguous sets, if you don't design your overloaded function sets with extreme care.

Hinweis

Die Mehrdeutigkeit überladener Funktionen kann erst bestimmt werden, wenn ein Funktions aufrufener auftritt.Ambiguity of overloaded functions can't be determined until a function call is encountered. An diesem Punkt werden die Sätze für jedes Argument im Funktionsaufruf erstellt, und Sie können bestimmen, ob eine eindeutige Überladung vorhanden ist.At that point, the sets are built for each argument in the function call, and you can determine whether an unambiguous overload exists. Dies bedeutet, dass Mehrdeutigkeiten im Code vorhanden sein dürfen, bis sie durch einen bestimmten Funktionsaufruf eindeutig deklariert werden.This means that ambiguities can remain in your code until they are evoked by a particular function call.

Unterschiede bei ArgumenttypenArgument Type Differences

Überladene Funktionen unterscheiden zwischen Argumenttypen, die verschiedene Initialisierer erfordern.Overloaded functions differentiate between argument types that take different initializers. Daher gelten ein Argument eines angegebenen Typs und ein Verweis auf diesen Typ für den Zweck des Überladens als identisch.Therefore, an argument of a given type and a reference to that type are considered the same for the purposes of overloading. Sie gelten als identisch, weil sie die gleichen Initialisierer erfordern.They are considered the same because they take the same initializers. max( double, double ) wird beispielsweise identisch mit max( double &, double & ) betrachtet.For example, max( double, double ) is considered the same as max( double &, double & ). Das Deklarieren von zwei solcher Funktionen verursacht einen Fehler.Declaring two such functions causes an error.

Aus demselben Grund werden Funktionsargumente eines Typs, der von oder geändert wird, const volatile nicht anders behandelt als der Basistyp für das überladen.For the same reason, function arguments of a type modified by const or volatile are not treated differently than the base type for the purposes of overloading.

Der überladende Funktionsmechanismus kann jedoch zwischen den von und qualifizierten verweisen const volatile und verweisen auf den Basistyp unterscheiden.However, the function overloading mechanism can distinguish between references that are qualified by const and volatile and references to the base type. Dadurch wird Code wie der folgende ermöglicht:It makes code such as the following possible:

// argument_type_differences.cpp
// compile with: /EHsc /W3
// C4521 expected
#include <iostream>

using namespace std;
class Over {
public:
   Over() { cout << "Over default constructor\n"; }
   Over( Over &o ) { cout << "Over&\n"; }
   Over( const Over &co ) { cout << "const Over&\n"; }
   Over( volatile Over &vo ) { cout << "volatile Over&\n"; }
};

int main() {
   Over o1;            // Calls default constructor.
   Over o2( o1 );      // Calls Over( Over& ).
   const Over o3;      // Calls default constructor.
   Over o4( o3 );      // Calls Over( const Over& ).
   volatile Over o5;   // Calls default constructor.
   Over o6( o5 );      // Calls Over( volatile Over& ).
}

OutputOutput

Over default constructor
Over&
Over default constructor
const Over&
Over default constructor
volatile Over&

Zeiger auf const - volatile Objekte und-Objekte werden auch als Zeiger auf den Basistyp für das überladen unterschiedlich betrachtet.Pointers to const and volatile objects are also considered different from pointers to the base type for the purposes of overloading.

Argumentübereinstimmung und KonvertierungenArgument matching and conversions

Wenn der Compiler versucht, die tatsächlichen Argumente mit den Argumenten in Funktionsdeklarationen abzugleichen, kann er Standardkonvertierungen oder benutzerdefinierte Konvertierungen bereitstellen, um den korrekten Typ zu erhalten, wenn keine genaue Übereinstimmung gefunden wird.When the compiler tries to match actual arguments against the arguments in function declarations, it can supply standard or user-defined conversions to obtain the correct type if no exact match can be found. Die Anwendung von Konvertierungen unterliegt diesen Regeln:The application of conversions is subject to these rules:

  • Sequenzen von Konvertierungen, die mehr als eine benutzerdefinierte Konvertierung enthalten, werden nicht berücksichtigt.Sequences of conversions that contain more than one user-defined conversion are not considered.

  • Sequenzen von Konvertierungen, die gekürzt werden können, indem Konvertierungen im Zwischenformat entfernt werden, werden nicht berücksichtigt.Sequences of conversions that can be shortened by removing intermediate conversions are not considered.

Das Ergebnis der Konvertierungssequenz, falls vorhanden, ist die am besten passende Sequenz.The resultant sequence of conversions, if any, is called the best matching sequence. Es gibt mehrere Möglichkeiten, ein Objekt vom Typ int unsigned long mithilfe von Standard Konvertierungen (in Standard Konvertierungenbeschrieben) in den Typ zu konvertieren:There are several ways to convert an object of type int to type unsigned long using standard conversions (described in Standard Conversions):

  • Konvertieren von int in long und dann von long in unsigned long .Convert from int to long and then from long to unsigned long.

  • Konvertieren von int in unsigned long .Convert from int to unsigned long.

Die erste Sequenz, obwohl Sie das gewünschte Ziel erreicht, ist nicht die beste übereinstimmende Sequenz – es gibt eine kürzere Sequenz.The first sequence, although it achieves the desired goal, isn't the best matching sequence — a shorter sequence exists.

Die folgende Tabelle zeigt eine Gruppe von Konvertierungen, die als triviale Konvertierungen bezeichnet werden, die eine begrenzte Auswirkung auf die Bestimmung haben, welche Sequenz die größte Übereinstimmung hat.The following table shows a group of conversions, called trivial conversions, that have a limited effect on determining which sequence is the best matching. Die Instanzen, in denen triviale Konvertierungen sich auf die Sequenzwahl auswirken, werden in der Liste nach der Tabelle behandelt.The instances in which trivial conversions affect choice of sequence are discussed in the list following the table.

Triviale KonvertierungenTrivial Conversions

Konvertieren von TypConvert from Type Konvertiert in TypConvert to Type
Typnametype-name Typname***&*type-name &
Typname***&*type-name & Typnametype-name
Typname []type-name [ ] Typname*type-name *
Typname ( Argument-List )type-name ( argument-list ) ( * Typname ) ( Argument-List )( * type-name ) ( argument-list )
Typnametype-name *const***Typnameconst type-name
Typnametype-name *volatile***Typnamevolatile type-name
Typname*type-name * *const***Typname*const type-name *
Typname*type-name * *volatile***Typname*volatile type-name *

Die Reihenfolge für Konvertierungen lautet wie folgt:The sequence in which conversions are attempted is as follows:

  1. Genaue Übereinstimmung.Exact match. Ein genaue Übereinstimmung zwischen den Typen, mit denen die Funktion aufgerufen wird und den Typen, die im Funktionsprototyp deklariert werden, ist immer die beste Übereinstimmung.An exact match between the types with which the function is called and the types declared in the function prototype is always the best match. Sequenzen von trivialen Konvertierungen werden als exakte Übereinstimmungen klassifiziert.Sequences of trivial conversions are classified as exact matches. Sequenzen, die diese Konvertierungen nicht vornehmen, werden jedoch besser als Sequenzen betrachtet, die konvertieren:However, sequences that don't make any of these conversions are considered better than sequences that convert:

    • Von Zeiger auf Zeiger auf const ( type * bis const type * ).From pointer, to pointer to const (type * to const type *).

    • Von Zeiger auf Zeiger auf volatile ( type * bis volatile type * ).From pointer, to pointer to volatile (type * to volatile type *).

    • From Reference, to Reference to const ( type & to const type & ).From reference, to reference to const (type & to const type &).

    • From Reference, to Reference to volatile ( type & to volatile type & ).From reference, to reference to volatile (type & to volatile type &).

  2. Übereinstimmung mithilfe von Erweiterungen.Match using promotions. Jede Sequenz, die nicht als exakte Entsprechung klassifiziert ist, die nur ganzzahlige herauf stufungen, Konvertierungen von float in double und triviale Konvertierungen enthält, wird als eine Entsprechung mithilfe vonAny sequence not classified as an exact match that contains only integral promotions, conversions from float to double, and trivial conversions is classified as a match using promotions. Obwohl eine Übereinstimmung mit Erweiterungen besser ist als eine Übereinstimmung, die Standardkonvertierungen verwendet, ist sie nicht so gut wie eine genaue Übereinstimmung.Although not as good a match as any exact match, a match using promotions is better than a match using standard conversions.

  3. Übereinstimmung mithilfe von Standardkonvertierungen.Match using standard conversions. Jede beliebige Sequenz, die nicht als genaue Übereinstimmung klassifiziert wird, oder eine Übereinstimmung mithilfe von Erweiterungen, die nur Standardkonvertierungen und triviale Konvertierungen enthält, wird als Übereinstimmung mithilfe von Standardkonvertierungen klassifiziert.Any sequence not classified as an exact match or a match using promotions that contains only standard conversions and trivial conversions is classified as a match using standard conversions. In dieser Kategorie gelten die folgenden Regeln:Within this category, the following rules are applied:

    • Die Konvertierung von einem Zeiger auf eine abgeleitete Klasse in einen Zeiger auf eine direkte oder indirekte Basisklasse ist der Konvertierung in void * oder vorzuziehen const void * .Conversion from a pointer to a derived class, to a pointer to a direct or indirect base class is preferable to converting to void * or const void *.

    • Die Konvertierung von einem Zeiger auf eine abgeleitete Klasse in einen Zeiger auf eine Basisklasse erzeugt eine bessere Übereinstimmung, je näher die Basisklasse der direkten Basisklasse ist.Conversion from a pointer to a derived class, to a pointer to a base class produces a better match the closer the base class is to a direct base class. Angenommen, die Klassenhierarchie folgt der in der folgenden Abbildung dargestellten Klassenhierarchie.Suppose the class hierarchy is as shown in the following figure.

Diagramm der bevorzugten KonvertierungenGraph of preferred conversions
Diagramm mit bevorzugten KonvertierungenGraph showing preferred conversions

Die Konvertierung von Typ D* in Typ C* ist der Konvertierung von Typ D* in Typ B* vorzuziehen.Conversion from type D* to type C* is preferable to conversion from type D* to type B*. Entsprechend ist die Konvertierung von Typ D* in Typ B* der Konvertierung von Typ D* in Typ A* vorzuziehen.Similarly, conversion from type D* to type B* is preferable to conversion from type D* to type A*.

Die gleiche Regel gilt für Verweiskonvertierungen.This same rule applies to reference conversions. Die Konvertierung von Typ D& in Typ C& ist der Konvertierung von Typ D& in Typ B& usw. vorzuziehen.Conversion from type D& to type C& is preferable to conversion from type D& to type B&, and so on.

Die gleiche Regel gilt für pointer-to-member-Konvertierungen.This same rule applies to pointer-to-member conversions. Die Konvertierung von Typ T D::* in Typ T C::* ist der Konvertierung von Typ T D::* in Typ T B::* und so weiter vorzuziehen (wobei T der Typ des Members ist).Conversion from type T D::* to type T C::* is preferable to conversion from type T D::* to type T B::*, and so on (where T is the type of the member).

Die vorhergehende Regel gilt nur für einen bestimmten Ableitungspfad.The preceding rule applies only along a given path of derivation. Betrachten Sie das Diagramm, das in der folgenden Abbildung dargestellt wird.Consider the graph shown in the following figure.

Mehrfache-Vererbung, die bevorzugte Konvertierungen anzeigtMultiple-inheritance that shows preferred conversions
Diagramm mit mehreren Vererbungen, das bevorzugte Konvertierungen anzeigtMultiple-inheritance graph that shows preferred conversions

Die Konvertierung von Typ C* in Typ B* ist der Konvertierung von Typ C* in Typ A* vorzuziehen.Conversion from type C* to type B* is preferable to conversion from type C* to type A*. Der Grund liegt darin, dass sie sich auf dem gleichen Pfad befinden, und B* näher liegt.The reason is that they are on the same path, and B* is closer. Allerdings ist die Konvertierung von Typ C* in Typ D* nicht der Konvertierung in den Typ vorzuziehen A* . es gibt keine Einstellung, da die Konvertierungen unterschiedlichen Pfaden folgen.However, conversion from type C* to type D* isn't preferable to conversion to type A*; there's no preference because the conversions follow different paths.

  1. Übereinstimmung mit benutzerdefinierten Konvertierungen.Match with user-defined conversions. Diese Sequenz kann nicht als exakte Entsprechung, eine Entsprechung mithilfe von Erweiterungen oder eine Entsprechung mithilfe von Standard Konvertierungen klassifiziert werden.This sequence can't be classified as an exact match, a match using promotions, or a match using standard conversions. Die Reihenfolge darf nur benutzerdefinierte Konvertierungen, Standardkonvertierungen oder triviale Konvertierungen enthalten, um die Übereinstimmung mit benutzerdefinierten Konvertierungen zu erreichen.The sequence must contain only user-defined conversions, standard conversions, or trivial conversions to be classified as a match with user-defined conversions. Eine Übereinstimmung mit benutzerdefinierten Konvertierungen gilt als eine bessere Übereinstimmung als eine Übereinstimmung mit einem Auslassungszeichen, jedoch als nicht so gut wie eine Übereinstimmung mit Standardkonvertierungen.A match with user-defined conversions is considered a better match than a match with an ellipsis but not as good a match as a match with standard conversions.

  2. Übereinstimmung mit einem Auslassungszeichen.Match with an ellipsis. Jede beliebige Sequenz, die Auslassungszeichen in der Deklaration entspricht, wird als Übereinstimmung mit einem Auslassungszeichen klassifiziert.Any sequence that matches an ellipsis in the declaration is classified as a match with an ellipsis. Dies wird als schwächste Treffer betrachtet.It's considered the weakest match.

Benutzerdefinierte Konvertierungen werden angewendet, wenn keine integrierte Erweiterung oder Konvertierung vorhanden ist.User-defined conversions are applied if no built-in promotion or conversion exists. Diese Konvertierungen werden auf der Grundlage des Typs des Arguments ausgewählt, das abgeglichen wird.These conversions are selected on the basis of the type of the argument being matched. Betrachten Sie folgenden Code:Consider the following code:

// argument_matching1.cpp
class UDC
{
public:
   operator int()
   {
      return 0;
   }
   operator long();
};

void Print( int i )
{
};

UDC udc;

int main()
{
   Print( udc );
}

Die verfügbaren benutzerdefinierten Konvertierungen für die-Klasse UDC sind vom Typ int und vom Typ long .The available user-defined conversions for class UDC are from type int and type long. Deshalb berücksichtigt der Compiler Konvertierungen für den Typ des Objekts, das abgeglichen wird: UDC.Therefore, the compiler considers conversions for the type of the object being matched: UDC. Eine Konvertierung in int ist vorhanden und wird ausgewählt.A conversion to int exists, and it is selected.

Während des Prozesseses zum Zuordnen von Argumenten können Standardkonvertierungen sowohl auf das Argument als auch auf das Ergebnis einer benutzerdefinierten Konvertierung angewendet werden.During the process of matching arguments, standard conversions can be applied to both the argument and the result of a user-defined conversion. Daher funktioniert der folgende Code:Therefore, the following code works:

void LogToFile( long l );
...
UDC udc;
LogToFile( udc );

Im vorherigen Beispiel wird die benutzerdefinierte Konvertierung ( Operator Long) aufgerufen, um in den- udc Typ zu konvertieren long .In the preceding example, the user-defined conversion, operator long, is invoked to convert udc to type long. Wenn keine benutzerdefinierte Konvertierung in den Typ long definiert wurde, würde die Konvertierung wie folgt verlaufen: der Typ UDC wurde int mithilfe der benutzerdefinierten Konvertierung in den Typ konvertiert.If no user-defined conversion to type long had been defined, the conversion would have proceeded as follows: Type UDC would have been converted to type int using the user-defined conversion. Dann würde die Standard Konvertierung von Typ int in Typ long angewendet, um dem Argument in der Deklaration zu entsprechen.Then the standard conversion from type int to type long would have been applied to match the argument in the declaration.

Wenn benutzerdefinierte Konvertierungen erforderlich sind, um einem Argument zu entsprechen, werden die Standard Konvertierungen beim Auswerten der besten Entsprechung nicht verwendet.If any user-defined conversions are required to match an argument, the standard conversions aren't used when evaluating the best match. Auch wenn mehr als eine Kandidaten Funktion eine benutzerdefinierte Konvertierung erfordert, werden die Funktionen als gleich betrachtet.Even if more than one candidate function requires a user-defined conversion, the functions are considered equal. Zum Beispiel:For example:

// argument_matching2.cpp
// C2668 expected
class UDC1
{
public:
   UDC1( int );  // User-defined conversion from int.
};

class UDC2
{
public:
   UDC2( long ); // User-defined conversion from long.
};

void Func( UDC1 );
void Func( UDC2 );

int main()
{
   Func( 1 );
}

Beide Versionen von Func erfordern eine benutzerdefinierte Konvertierung, um den Typ int in das Klassentyp Argument zu konvertieren.Both versions of Func require a user-defined conversion to convert type int to the class type argument. Mögliche Konversionen sind:The possible conversions are:

  • Konvertieren von Typ int in Typ UDC1 (eine benutzerdefinierte Konvertierung).Convert from type int to type UDC1 (a user-defined conversion).

  • Konvertieren Sie von Typ int in Typ long , und konvertieren Sie dann in Typ UDC2 (eine zweistufige Konvertierung).Convert from type int to type long; then convert to type UDC2 (a two-step conversion).

Obwohl das zweite eine Standard Konvertierung und die benutzerdefinierte Konvertierung erfordert, werden die beiden Konvertierungen weiterhin als gleich betrachtet.Even though the second one requires both a standard conversion and the user-defined conversion, the two conversions are still considered equal.

Hinweis

Benutzerdefinierte Konvertierungen gelten als Konvertierung durch Konstruktion oder als Konvertierung durch Initialisierung (Konvertierungsfunktion).User-defined conversions are considered conversion by construction or conversion by initialization (conversion function). Beide Methoden werden als gleich betrachtet, wenn die beste Übereinstimmung berücksichtigt wird.Both methods are considered equal when considering the best match.

Argumentübereinstimmung und der this-ZeigerArgument matching and the this pointer

Klassenmember-Funktionen werden unterschiedlich behandelt, je nachdem, ob Sie als deklariert werden static .Class member functions are treated differently, depending on whether they are declared as static. Da nicht statische Funktionen über ein implizites Argument verfügen, das den this Zeiger bereitstellt, werden nicht statische Funktionen als ein Argument bezeichnet, das als statische Funktionen fungiert. andernfalls werden Sie identisch deklariert.Because nonstatic functions have an implicit argument that supplies the this pointer, nonstatic functions are considered to have one more argument than static functions; otherwise, they are declared identically.

Diese nicht statischen Member-Funktionen erfordern, dass der implizite this Zeiger dem Objekttyp entspricht, über den die Funktion aufgerufen wird, oder für überladene Operatoren erfordern Sie, dass das erste Argument mit dem Objekt identisch ist, auf das der Operator angewendet wird.These nonstatic member functions require that the implied this pointer match the object type through which the function is being called, or, for overloaded operators, they require that the first argument match the object on which the operator is being applied. (Weitere Informationen zu überladenen Operatoren finden Sie unter überladene Operatoren.)(For more information about overloaded operators, see Overloaded Operators.)

Anders als bei anderen Argumenten in überladenen Funktionen werden keine temporären Objekte eingeführt, und es wird versucht, eine Entsprechung für das this Zeigerargument zu finden.Unlike other arguments in overloaded functions, no temporary objects are introduced and no conversions are attempted when trying to match the this pointer argument.

Wenn der -> Member-Selection-Operator verwendet wird, um auf eine Member-Funktion der Klasse zuzugreifen class_name , this weist das Zeigerargument den Typ auf class_name * const .When the -> member-selection operator is used to access a member function of class class_name, the this pointer argument has a type of class_name * const. Wenn die Member als oder deklariert const werden volatile , sind die Typen const class_name * const volatile class_name * const bzw..If the members are declared as const or volatile, the types are const class_name * const and volatile class_name * const, respectively.

Der Memberauswahloperator . funktioniert genau auf die gleiche Weise, außer dass ein impliziter &-Operator (address-of) dem Objektnamen vorangestellt ist.The . member-selection operator works exactly the same way, except that an implicit & (address-of) operator is prefixed to the object name. Im folgenden Beispiel wird gezeigt, wie dies funktioniert:The following example shows how this works:

// Expression encountered in code
obj.name

// How the compiler treats it
(&obj)->name

Der linke Operand der Operatoren ->* und .* (Zeiger auf Member) wird hinsichtlich der Argumentübereinstimmung genauso wie der .-Operator und der ->-Operator (Memberauswahl) behandelt.The left operand of the ->* and .* (pointer to member) operators are treated the same way as the . and -> (member-selection) operators with respect to argument matching.

Ref-Qualifizierer für Element FunktionenRef-qualifiers on member functions

Verweis Qualifizierer ermöglichen es, eine Element Funktion zu überladen, je nachdem, ob das Objekt, auf das von gezeigt this wird, ein rvalue-Wert oder ein Lvalue ist.Ref qualifiers make it possible to overload a member function on the basis of whether the object pointed to by this is an rvalue or an lvalue. Diese Funktion kann verwendet werden, um unnötige Kopiervorgänge in Szenarios zu vermeiden, in denen Sie keinen Zeiger Zugriff auf die Daten bereitstellen möchten.This feature can be used to avoid unnecessary copy operations in scenarios where you choose not to provide pointer access to the data. Nehmen Sie beispielsweise an, die Klasse C initialisiert einige Daten in Ihrem Konstruktor und gibt eine Kopie dieser Daten in der Member-Funktion zurück get_data() .For example, assume class C initializes some data in its constructor, and returns a copy of that data in member function get_data(). Wenn ein Objekt vom Typ C ein rvalue ist, das zerstört werden soll, wählt der Compiler die-Überladung aus get_data() && , die die Daten verschiebt, anstatt Sie zu kopieren.If an object of type C is an rvalue that is about to be destroyed, then the compiler will choose the get_data() && overload, which moves the data rather than copy it.

#include <iostream>
#include <vector>

using namespace std;

class C
{

public:
    C() {/*expensive initialization*/}
    vector<unsigned> get_data() &
    {
        cout << "lvalue\n";
        return _data;
    }
    vector<unsigned> get_data() &&
    {
        cout << "rvalue\n";
        return std::move(_data);
    }

private:
    vector<unsigned> _data;
};

int main()
{
    C c;
    auto v = c.get_data(); // get a copy. prints "lvalue".
    auto v2 = C().get_data(); // get the original. prints "rvalue"
    return 0;
}

Einschränkungen beim ÜberladenRestrictions on overloading

Mehrere Einschränkungen steuern eine akzeptable Gruppe von überladenen Funktionen:Several restrictions govern an acceptable set of overloaded functions:

  • Zwei beliebige Funktionen in einer Gruppe von überladenen Funktionen müssen unterschiedliche Argumentlisten haben.Any two functions in a set of overloaded functions must have different argument lists.

  • Das Überladen von Funktionen mit Argumentlisten der gleichen Typen auf alleiniger Grundlage des Rückgabetyps ist ein Fehler.Overloading functions with argument lists of the same types, based on return type alone, is an error.

    Microsoft-spezifischMicrosoft Specific

Sie können den Operator new nur auf Grundlage des Rückgabe Typs überladen – insbesondere auf Grundlage des angegebenen Speicher modellmodifizierers.You can overload operator new solely on the basis of return type — specifically, on the basis of the memory-model modifier specified.

Ende Microsoft-spezifischEND Microsoft Specific

  • Element Funktionen können nicht nur auf Basis der statischen und der anderen nicht statischen überladen werden.Member functions can't be overloaded solely on the basis of one being static and the other nonstatic.

  • typedef Deklarationen definieren keine neuen Typen. Sie führen Synonyme für vorhandene Typen ein.typedef declarations do not define new types; they introduce synonyms for existing types. Sie wirken sich nicht auf den Überladungsmechanismus aus.They don't affect the overloading mechanism. Betrachten Sie folgenden Code:Consider the following code:

    typedef char * PSTR;
    
    void Print( char *szToPrint );
    void Print( PSTR szToPrint );
    

    Die vorhergehenden zwei Funktionen verfügen über identische Argumentlisten.The preceding two functions have identical argument lists. PSTR ist ein Synonym für den Typ char * .PSTR is a synonym for type char *. Im Memberbereich generiert dieser Code einen Fehler.In member scope, this code generates an error.

  • Aufgelistete Typen sind verschiedene Typen und können verwendet werden, um zwischen überladenen Funktionen zu unterscheiden.Enumerated types are distinct types and can be used to distinguish between overloaded functions.

  • Die Typen "Array von" und "Zeiger auf" werden für die Unterscheidung zwischen überladenen Funktionen als identisch angesehen, aber nur für einzeln dimensionierte Arrays.The types "array of " and "pointer to" are considered identical for the purposes of distinguishing between overloaded functions, but only for singly dimensioned arrays. Daher verursachen diese überladenen Funktionen einen Konflikt und generieren eine Fehlermeldung:That's why these overloaded functions conflict and generate an error message:

    void Print( char *szToPrint );
    void Print( char szToPrint[] );
    

    Für mehrdimensionale Arrays gelten die zweite und alle nachfolgenden Dimensionen als Teil des Typs.For multiply dimensioned arrays, the second and all succeeding dimensions are considered part of the type. Deshalb werden sie beim Unterscheiden zwischen überladenen Funktionen verwendet:Therefore, they are used in distinguishing between overloaded functions:

    void Print( char szToPrint[] );
    void Print( char szToPrint[][7] );
    void Print( char szToPrint[][9][42] );
    

Überladung, überschreiben und ausblendenOverloading, overriding, and hiding

Zwei beliebige Funktionsdeklarationen des gleichen Namens im gleichen Bereich können auf die gleiche Funktion oder zwei einzelne Funktionen, die überladen werden, verweisen.Any two function declarations of the same name in the same scope can refer to the same function, or to two discrete functions that are overloaded. Wenn die Argumentlisten der Deklarationen Argumente äquivalenter Typen enthalten (wie im vorherigen Abschnitt beschrieben), beziehen sich die Funktionsdeklarationen auf die gleiche Funktion.If the argument lists of the declarations contain arguments of equivalent types (as described in the previous section), the function declarations refer to the same function. Andernfalls beziehen sie sich auf zwei separate Funktionen, die mithilfe des Überladens ausgewählt werden.Otherwise, they refer to two different functions that are selected using overloading.

Der Klassen Bereich wird strikt beachtet. Daher befindet sich eine Funktion, die in einer Basisklasse deklariert wird, nicht im selben Bereich wie eine Funktion, die in einer abgeleiteten Klasse deklariert ist.Class scope is strictly observed; therefore, a function declared in a base class isn't in the same scope as a function declared in a derived class. Wenn eine Funktion in einer abgeleiteten Klasse mit dem gleichen Namen wie eine virtuelle Funktion in der Basisklasse deklariert wird, über schreibt die Funktion der abgeleiteten Klasse die Basisklassen Funktion.If a function in a derived class is declared with the same name as a virtual function in the base class, the derived-class function overrides the base-class function. Weitere Informationen finden Sie unter virtuelle Funktionen.For more information, see Virtual Functions.

Wenn die Basisklassen Funktion nicht als "Virtual" deklariert ist, wird Sie von der abgeleiteten Klassen Funktion ausgeblendet .If the base class function isn't declared as 'virtual', then the derived class function is said to hide it. Sowohl das Überschreiben als auch das Ausblenden unterscheiden sich vom überladen.Both overriding and hiding are distinct from overloading.

Block Bereich wird strikt beachtet. Daher befindet sich eine Funktion, die im Datei Bereich deklariert ist, nicht im selben Bereich wie eine lokal deklarierte Funktion.Block scope is strictly observed; therefore, a function declared in file scope isn't in the same scope as a function declared locally. Wenn eine lokal deklarierte Funktion den gleichen Namen wie eine Funktion besitzt, die im Dateibereich deklariert wird, blendet die lokal deklarierte Funktion die Funktion im Dateibereich aus, und es erfolgt keine Überladung.If a locally declared function has the same name as a function declared in file scope, the locally declared function hides the file-scoped function instead of causing overloading. Zum Beispiel:For example:

// declaration_matching1.cpp
// compile with: /EHsc
#include <iostream>

using namespace std;
void func( int i )
{
    cout << "Called file-scoped func : " << i << endl;
}

void func( char *sz )
{
   cout << "Called locally declared func : " << sz << endl;
}

int main()
{
   // Declare func local to main.
   extern void func( char *sz );

   func( 3 );   // C2664 Error. func( int ) is hidden.
   func( "s" );
}

Der vorhergehende Code zeigt zwei Definitionen der Funktion func.The preceding code shows two definitions from the function func. Die Definition, die ein Argument vom Typ annimmt, char * ist aufgrund der-Anweisung auf local fest main extern .The definition that takes an argument of type char * is local to main because of the extern statement. Daher wird die Definition, die ein Argument vom Typ annimmt int , ausgeblendet, und der erste-Vorgang func ist fehlerhaft.Therefore, the definition that takes an argument of type int is hidden, and the first call to func is in error.

Für überladene Memberfunktionen können verschiedenen Versionen der Funktion unterschiedliche Zugriffsrechte zugewiesen werden.For overloaded member functions, different versions of the function can be given different access privileges. Sie werden weiterhin als im Gültigkeitsbereich der einschließenden Klasse betrachtet und sind somit überladene Funktionen.They are still considered to be in the scope of the enclosing class and thus are overloaded functions. Betrachten Sie den folgenden Code, in dem die Memberfunktion Deposit überladen wird. Eine Version ist öffentlich, die andere privat.Consider the following code, in which the member function Deposit is overloaded; one version is public, the other, private.

Der Zweck dieses Beispiels ist es, eine Account-Klasse bereitzustellen, in der ein korrektes Kennwort erforderlich ist, um Eingaben vorzunehmen.The intent of this sample is to provide an Account class in which a correct password is required to perform deposits. Dies erfolgt mithilfe von überladen.It's done by using overloading.

Der Aufruf von Deposit in Account::Deposit Ruft die private Member-Funktion auf.The call to Deposit in Account::Deposit calls the private member function. Dieser Befehl ist korrekt Account::Deposit , weil eine Member-Funktion ist und Zugriff auf die privaten Member der-Klasse hat.This call is correct because Account::Deposit is a member function, and has access to the private members of the class.

// declaration_matching2.cpp
class Account
{
public:
   Account()
   {
   }
   double Deposit( double dAmount, char *szPassword );

private:
   double Deposit( double dAmount )
   {
      return 0.0;
   }
   int Validate( char *szPassword )
   {
      return 0;
   }

};

int main()
{
    // Allocate a new object of type Account.
    Account *pAcct = new Account;

    // Deposit $57.22. Error: calls a private function.
    // pAcct->Deposit( 57.22 );

    // Deposit $57.22 and supply a password. OK: calls a
    //  public function.
    pAcct->Deposit( 52.77, "pswd" );
}

double Account::Deposit( double dAmount, char *szPassword )
{
   if ( Validate( szPassword ) )
      return Deposit( dAmount );
   else
      return 0.0;
}

Siehe auchSee also

Funktionen (C++)Functions (C++)