Wie viele Konstruktoren hat die Klasse haben?
Ich bin der Vorbereitung für eine kommende C++ - Klausur und bin auf diese Frage zu Klassen und Konstruktoren:
Wie viele Konstruktoren hat die Klasse Anteil haben?"
class Fraction { //... public: Fraction(int numerator = 0, int denominator = 1); //... };
Dachte ich, es ist nur eine, aber Sie schlug es drei:
Fraction();
Fraction(n);
Fraction(n, d);
Oder in anderen Worten:
Ist eine Funktion mit default-Werten eine überladene Funktion?
- Tatsächlich gibt es drei Aufruf-Varianten, die verwendet werden können, aber es gibt nur einen Konstruktor. Das ist entweder eine Fangfrage, oder fragte unklar. Sollte schon "Wie viele Konstruktor-Aufruf Kandidaten hat die Klasse Anteil haben?" Schlechte Frage anders, Klagen Sie, wenn Sie die Prüfung nicht besteht, weil der, dass :-P.
- Für Ihre Frage, überladen, für was eigentlich?
- Es gibt auch implizit deklariert kopieren und verschieben von Konstruktoren...
- Es kommt darauf an, ob Sie hat Ihnen diesen 3-Konstruktor aufrufen, um zu "beweisen", dass es 3 Konstruktoren, wenn das der Fall ist Sie sind wahrscheinlich unzureichend. Sie haben wahrscheinlich die Antwort 3, die Grafen implizit generierte Konstruktoren als gut, aber ohne die Aufklärung oder das wissen, dass das der Fall ist, so warfen Sie, dass verwirrend Unsinn zu simulieren, Angemessenheit, in der Hoffnung, Sie erhalten Weg mit es und kommen Sie nicht zu Fragen, hier über SO 🙂
- Blick auf die erzeugte Maschinen-code und Sie werden sehen, diese drei ruft alle rufen die gleiche routine - und der "Standard" - Argumente vorhanden sind (geschoben oder in den Registern, soweit angemessen) auf den Ruf Website. Also "Sie" sind falsch.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Es ist nur ein Konstruktor der entsprechenden Erklärung gepostet, nicht drei überladungen.
Anrufe
sind äquivalent:
Eine weitere Möglichkeit, sich selbst davon zu überzeugen, dass es nur ein Konstruktor der entsprechenden Erklärung ist, dass Sie brauchen nur zu definieren, der einen Konstruktor, nicht drei.
Den Abschnitt der C++11 standard auf Standard-Argumente hat diese:
Nun die wichtigste Frage.
Wenn die person, gerahmt Frage möchte move-Konstruktor und der kopierkonstruktor, die implizit vom compiler generiert, wenn Sie explizit gelöscht, in der Menge der Konstruktoren, dann die Antwort ist drei. In diesem Fall, die Frage ist eine Fangfrage.
Fraction
, das ist doch sehr unwahrscheinlich.Nicht. Überlastungen Aussehen
und haben jeweils eine eigene Implementierung (definition), während eine Funktion mit default-Parameter hat eine einzelne Implementierung.
Es ist eine Fangfrage, entworfen, um zu täuschen, Sie zeigt die verfügbaren Aufruf-Varianten für eine einzigen Konstruktor Erklärung.
Den bestimmte Antwort für das gegebene code-snippet ist 3 (in Worten drei).
Gibt es einen spezialisierten Konstruktor (dient drei Varianten der Berufung), und der compiler generiert copy-und move-Konstruktor automatisch, wenn man nicht
delete
Ihnen, oder geben Sie eine benutzerdefinierte Implementierung:Also für eine solche Prüfung, wenn Sie Antwort
Dass das falsch sowieso. Wenn Sie die Antwort
müssen Sie erklären, in der Tiefe, warum Sie so denken (wie oben erläutert).
In jeder mündlichen Prüfung, würde ich Sie bitten, backup, warum genau, so würde ich dies in einem azubi-test.
Die Antwort auf Ihre Frage ist relativ zu diesen drei follow-up-Fragen:
Die explizite definition ist nur ein Konstruktor, den der compiler fügt einen drei-argument aufrufen, unabhängig davon, ob der Anruf explizit liefert 0, 1, oder 2 Argumente.
In der vor-'11 gibt es keine move-Konstruktoren, in '11 gibt es zwei implizite Konstruktor-Definitionen
Fraction(const Fraction &) noexcept
undFraction(Fraction &&) noexcept
, überprüfen Sie die zugänglich cppreference, in '14 sich die Regeln, wenn es eine implizit definiert move-Konstruktor ändern.Die Frage, die Sie haben ist leider unschuldig aussehenden, aber ziemlich technisch; ich hoffe, dass Ihre Klasse nicht darauf bestehen, zu kurz gedacht C++, es ist der schlechteste Weg, um es zu lernen.
Haben Sie nur eine Deklaration eines Konstruktors.
Auf der anderen Seite:
Weil das so ist, würde ich nicht verwenden, der Begriff überlastet hier.
Diese Art der Funktionsdefinition definiert eine einzelne Funktion, sondern 2 zusätzliche Aufruf-Syntax. Der feine Unterschied wird deutlich, wenn die Einnahme von Funktionszeigern oder Anpassung einer Vorlage-Funktion argument, um überladene Funktionen: in diesem Fall müssen Sie nur eine Funktion mit full-argument-Liste als verfügbar überlastet Typ.
Nun die heikle Sache ist, dass wir reden über einen Konstruktor hier, und Sie einen Konstruktor nicht engagieren in der gleichen Art von überlastung Auflösung als gewöhnliche Funktion und ist für alle Zwecke, nicht zugänglich, andere als syntaktisch. Insbesondere diese definition hat zählen separat als Standard-Konstruktor. Es gilt auch als separat-converting-constructor from int und kann verwendet werden, als ((Bruchteil)3).
Also für alle praktischen Zwecke, es stellt drei verschiedene syntaktische Personen im Konstruktor Kategorie. Und im Gegensatz zu normalen Funktionen, es gibt keinen funktionalen Zusammenhang, wo die überlast Auflösung würde aussetzen der Unterschied zwischen den drei eigentlichen Funktion Signaturen und drei lediglich syntaktische Aufrufkonventionen.
Dies ist nicht eine gute Frage für eine schriftliche Prüfung. Das ist wirklich etwas für eine mündliche Prüfung, da gibt es so viele Feinheiten, die beteiligten, den Unterschied zwischen einer formal richtigen Antwort (wenn überhaupt) und eine formal falsche Antwort ist wahrscheinlich nicht zu korrelieren gut mit dem tatsächlichen wissen und können, und die Argumentation, die hinter jeder Antwort wichtiger als die Antwort selbst.
Da kommt es auf die Argumente, die Sie weitergeben:
Also es gibt 3 Konstruktoren. Keine überladung statt.
Können Sie erstellen, die Bruch-Objekt auf drei verschiedene Arten mit dem einzigen Konstruktor deklariert int über Klasse. Konstruktor enthält die default-Parameter. Wenn Sie nicht übergeben, das argument, es übernimmt der jeweilige Wert für das argument.
Fraction a;
//Zähler 0 und im Nenner 1
Fraction a(10);
//Zähler wird 10 und Nenner wird 1
Fraction a(10, 20);
//Zähler wird 10 und Nenner werden 20