2016-05-09 15 views
1

Ich habe ein Stück Code wie folgt aus: etwas über Art UnverträglichkeitGibt es eine gute Regel für die Verwendung von 'const' in Klassen und Operatorüberladungen in C++?

class EducationalCentre 
{ 
    string _centreName; 
    vector<Course> _courses; // courses offered by the Centre 
    Collection<Course*, Student*, 150> _applicants; 

public: 
    EducationalCentre(string name="<name>") 
    { 
     _centreName = name; 
    } 

    EducationalCentre(const EducationalCentre& obj) 
     :_courses(obj._courses), _applicants(obj._applicants) 
    { 
     _centreName = obj._centreName; 
    } 
}; 

, nun in diesem Teil Header _applicants(obj._applicants) Kopie Bau, gibt es eine verschnörkelt rote Linie um (obj, es ist der Fehler sagt schwebt (const erwähnt wird) .

Da ich in diesem Stadium nichts ändern möchte (dies ist ein Teil des Prüfungstests) - würde ich gerne wissen, warum das passiert.

Ich habe versucht, die const von EducationalCentre(const EducationalCentre& obj) zu entfernen und das löst das Problem tatsächlich aber .. Wie gesagt, ich würde eher darüber lernen, was das verursacht, anstatt es zu entfernen.

+0

Wie sieht der Kopierkonstruktor von 'Collection' aus? Auch wenn Sie kompilieren, was ist die eigentliche Fehlermeldung, die Sie erhalten? – NathanOliver

+3

'Collection' copy ctor mit einem nichtkonstanten Argument würde dieses Verhalten erklären. Copy ctor sollte ein Const-Argument nehmen. –

+3

Wegkommen von "squiggly roten Linien". Ihr Code muss den Compiler und nicht die IDE übergeben! –

Antwort

5

Regel const für die Verwendung ist, es zu benutzen, wenn Sie

Natürlich kann :), wie bei allen Best Practices gibt es Ausnahmen, aber im Allgemeinen sollten Sie immer danach streben, nicht-statische Methoden const wenn sie don zu machen den Zustand des Objekts nicht mutieren.

Der Grund für das Problem, das Sie erhalten, ist, dass Collection Kopierkonstruktor einen nichtkonstanten Verweis auf die Instanz verwendet, die es als Quellobjekt verwendet.

Kopieren Konstruktor kann const oder nicht-const Referenz als sein Argument, aber, IMO, nicht-const sollte nur verwendet werden, wenn Sie keine Wahl haben, die selten ist. Das Erstellen eines Objekts basierend auf einem anderen Objekt sollte das Quellobjekt nicht ändern, daher sollte es als const markiert sein.

Wie ich in dem Kommentar bemerkte, hat die Klasse, die generisch ist, nichts mit Kopie ctor zu tun, die const Referenz nimmt. In der Tat, wenn Sie sich z.B. std::vector Sie werden sehen, dass es einen Kopierkonstruktor hat, der eine const-Referenz verwendet. Wahrscheinlich sind einige der Methoden, die Sie in Collection kopieren Konstruktor auf Ihr Argument ist nicht-const, und deshalb können Sie nicht const config. Die Lösung besteht darin, auch die beleidigende Methode zu ändern. Dies bringt uns zu einem wichtigen Punkt: const ist viral. Wenn Sie eine Methode const markieren, müssen alle anderen selbst aufgerufenen Methoden const sein. Gleiches gilt für Aufrufmethoden für konstante Objekte - Sie können nur konstante Methoden aufrufen. Wenn Sie es nicht von Anfang an tun, können Sie in einer Situation landen, in der das Ändern einer ganzen Kette von Methoden zu einer Methode führt, so dass es einfacher ist, aufzugeben.

Warum Konstanz ist gut: Die meisten Bugs werden durch eine unerwartete Änderung des Anwendungsstatus verursacht - fragen Sie einfach nur funktionale Programmfans, die von Unveränderlichkeit schwärmen :). Eine const-Methode kann den Zustand des Objekts nicht ändern, so dass die Möglichkeit unerwarteter Änderungen ausgeschlossen wird: z. Wenn eine Exception mitten in einer const-Methode ausgelöst wird, können Sie sicher sein, dass das Objekt nicht in einem halb-modifizierten Zustand vorliegt, der Klasseninvarianten für ungültig erklärt.

Nun, C++ ist nicht nur eine objektorientierte Sprache, so können Sie den Anwendungszustand auf andere Weise ändern, und auch können Sie mutable und const_cast missbrauchen den Compiler zu betrügen, aber const hilft bei der das Schreiben richtige Software viel mit und die Debugging-Bemühungen verringern.