Standardparameter mit C ++ - Konstruktoren
Ist es gute Praxis, einen Klassen-Konstruktor verwendet, default-Parameter, oder sollte ich separate überladene Konstruktoren? Zum Beispiel:
//Use this...
class foo
{
private:
std::string name_;
unsigned int age_;
public:
foo(const std::string& name = "", const unsigned int age = 0) :
name_(name),
age_(age)
{
...
}
};
//Or this?
class foo
{
private:
std::string name_;
unsigned int age_;
public:
foo() :
name_(""),
age_(0)
{
}
foo(const std::string& name, const unsigned int age) :
name_(name),
age_(age)
{
...
}
};
Entweder version scheint zu funktionieren, z.B.:
foo f1;
foo f2("Name", 30);
Welchen Stil Sie bevorzugen bzw. empfehlen und warum?
InformationsquelleAutor der Frage Rob | 2008-10-09
Du musst angemeldet sein, um einen Kommentar abzugeben.
Definitiv eine Frage des Stils. Ich bevorzuge Konstruktoren mit default-Parametern, so lange, wie die Parameter sinnvoll. Klassen in der standard-verwenden Sie Sie als gut, das spricht zu Ihren Gunsten.
Einer Sache zu beachten ist, wenn Sie die Standardwerte für alle parameter, Ihre Klasse kann implizit aus, dass die parameter-Typ. Check-out dieser thread für mehr info.
InformationsquelleAutor der Antwort luke
Ich würde gehen mit den default-Argumente, vor allem, da C++ nicht lassen Sie die Kette von Konstruktoren (so dass Sie am Ende mit, um das Duplikat des initialiser Liste, und möglicherweise mehr, für jede überlastung).
Dieser sagte, gibt es einige Fallstricke, die mit Standard-Argumenten, einschließlich der Tatsache, dass die Konstanten können eingebettet und damit Teil der Klasse' binary interface). Andere zu achten ist, dass das hinzufügen von default-Argumenten kann eine explizite multi-argument-Konstruktor in eine implizite ein-argument-Konstruktor:
InformationsquelleAutor der Antwort Sam Stokes
Meiner Erfahrung nach Standard-Parameter scheinen cool zu der Zeit, und meine Faulheit Faktor glücklich, aber dann unten auf der Straße ich bin mit der Klasse und ich bin überrascht, wenn die Standard-kicks in. Also ich glaube nicht wirklich, es ist eine gute Idee; besser eine className::className() und dann eine className::init(arglist). Nur für die, die die Wartbarkeit Rand.
InformationsquelleAutor der Antwort Paul Nathan
Dieser Diskussion gelten sowohl für Bauherren, aber auch Methoden und Funktionen.
Mit Standard-Parametern?
Die gute Sache ist, dass Sie brauchen nicht zu überladen-Konstruktoren/Methoden/Funktionen für jeden Fall:
Das schlimme ist, dass müssen Sie erklären, Ihren Standard in der Kopfzeile, so dass Sie eine versteckte Abhängigkeit: Wie, wenn Sie ändern Sie den code einer inline-Funktion, wenn Sie den Standardwert ändern, in Ihrem Kopf, müssen Sie kompilieren Sie alle Quellen mit diesem header sicher, dass Sie sich mit dem neuen Standard.
Wenn Sie nicht, die Quellen werden noch die alten default-Wert.
mit überladenen Konstruktoren/Methoden/Funktionen?
Die gute Sache ist, dass, wenn Ihre Funktionen nicht inlined, dann Steuern Sie den Standardwert in der Quelle, indem Sie, wie eine Funktion verhält. Zum Beispiel:
Das problem ist, dass Sie zu pflegen haben mehrere Konstruktoren/Methoden/Funktionen und Ihren Versand.
InformationsquelleAutor der Antwort paercebal
Sam ' s Antwort gibt der Grund, dass die Standard-Argumente sind besser für Konstruktoren eher als zu überladen. Ich möchte nur hinzufügen, dass C++-0x ermöglichen delegation von einem Konstruktor zu einem anderen, wodurch die Notwendigkeit für Standardwerte.
InformationsquelleAutor der Antwort Richard Corden
Entweder Ansatz funktioniert. Aber wenn Sie eine lange Liste der optionalen Parameter einen default-Konstruktor, und dann haben Sie Ihre set-Funktion return eine Referenz auf dieses. Dann die Kette settors.
Nun bei der Konstruktion der Objekte, die Sie können wählen Sie eine wählen Sie, welche Eigenschaften außer Kraft zu setzen und die diejenigen, die Sie eingestellt haben, werden explizit benannt. Sehr viel besser lesbar 🙂
Auch, Sie müssen nicht mehr zu erinnern, die Reihenfolge der Argumente an den Konstruktor übergeben.
InformationsquelleAutor der Antwort Rodney Schuler
Wenn die Erstellung von Konstruktoren mit Argumenten ist schlecht (wie viele behaupten würden), dann machen Sie mit default-Argumenten ist noch schlimmer. Ich habe vor kurzem begonnen, um zu kommen zu der Meinung, dass ctor Argumente sind schlecht, weil Ihre ctor Logik sollte so gering wie möglich. Wie gehen Sie mit der Fehlerbehandlung in den ctor, sollte jemand ein argument übergeben, das macht keinen Sinn? Sie können entweder werfen Sie eine Ausnahme, das ist die schlechte Nachricht, es sei denn, alle Ihre Anrufer bereit sind, wickeln Sie jeden "neuen" Anrufe innerhalb des try-Blöcke, oder die Einstellung einiger "wird initialisiert" member-variable ist, was ein dirty hack.
Daher der einzige Weg, um sicherzustellen, dass die übergebenen Argumente in der Initialisierung Phase Ihres Objekts ist die Einrichtung einer separaten Methode initialize() wo können Sie die return-code.
Die Verwendung von default-Argumenten ist schlecht, aus zwei Gründen; Erstens, wenn Sie hinzufügen möchten, ein weiteres argument für die ctor, dann ist Sie stecken geblieben sind, setzen Sie am Anfang und ändern die gesamte API. Zudem werden die meisten Programmierer daran gewöhnt sind, um herauszufinden, eine API, die durch die Art und Weise, dass es in der Praxis verwendet-das ist besonders gilt für nicht-öffentliche API ' s verwendet innerhalb einer Organisation, wo formale Dokumentation nicht vorhanden. Wenn andere Programmierer sehen, dass die Mehrheit der Anrufe, enthalten keine Argumente, Sie werden das gleiche tun, die restlichen selig nicht bewusst das Standardverhalten Ihre Standard-Argumente gegen Sie.
Es ist auch erwähnenswert, dass die google C++ style guide meidet sowohl ctor Argumente (es sei denn absolut notwendig), und Standard-Argumente, die an Funktionen oder Methoden.
InformationsquelleAutor der Antwort Nik Reiman
Ich würde mit den default-Parametern, aus diesem Grund: Ihr Beispiel wird davon ausgegangen, dass die ctor-Parameter entsprechen direkt auf member-Variablen. Aber was, wenn das nicht der Fall ist, und Sie haben zur Bearbeitung der Parameter, bevor das Objekt initialisiert werden. Mit einem gemeinsamen Tor wäre der beste Weg zu gehen.
InformationsquelleAutor der Antwort James Curran
Meist persönliche Wahl. Jedoch, überlast-alles tun können default-parameter machen kann, aber nicht Umgekehrt.
Beispiel:
Können Sie überlastung zu schreiben(int x, foo& a) und A(int x), aber Sie können nicht verwenden Sie die Standard-parameter zu schreiben(int x, foo& = null).
Die Allgemeine Regel ist, zu verwenden, was Sinn macht, und macht den code besser lesbar.
InformationsquelleAutor der Antwort Yang Lu
Eine weitere Sache zu prüfen ist, ob oder nicht die Klasse kann verwendet werden, in einem array:
In diesem Szenario gibt es keinen Vorteil der Verwendung der default-parameter.
Sicherlich würde dies NICHT funktionieren:
InformationsquelleAutor der Antwort peter
Eine Sache, die mich stört, mit default-Parametern ist, dass Sie können nicht geben Sie den letzten Parameter, sondern die default-Werte für die ersten. Zum Beispiel, in Ihrem code, Sie können nicht erstellen Sie ein Foo mit keine Namen, aber einem bestimmten Alter (wenn ich mich richtig erinnere, ist dies möglich in C++0x mit der einheitlichen Bau-syntax). Manchmal macht dies Sinn, aber es kann auch sein, wirklich umständlich.
Meiner Meinung nach, gibt es keine Faustregel. Personnaly, ich Neige dazu, verwenden Sie mehrere überladene Konstruktoren (oder Methoden), außer wenn nur das Letzte argument muss ein default-Wert.
InformationsquelleAutor der Antwort Luc Touraille
Frage des Stils, aber wie Matt schon sagte, auf jeden Fall prüfen, Kennzeichnung Konstruktoren mit default-Argumente, die es erlauben würde, eine implizite Konvertierung als 'explicit vermeiden Sie eine unbeabsichtigte automatische Konvertierung. Es ist keine Voraussetzung (und es könnte nicht besser sein, wenn Sie eine wrapper-Klasse, die Sie wollen, um implizit zu konvertieren), aber es kann verhindern, dass Fehler.
Mir persönlich gefällt der Standard-wenn angebracht, denn die mag ich nicht wiederholt-code. YMMV.
InformationsquelleAutor der Antwort Nick