Vermeiden Sie Kopie nach Wert beim Initialisieren der Referenz
-
25-10-2019 - |
Frage
Ich habe eine Funktionsschnittstelle:
struct iFace {
virtual Type& getType() = 0;
}
Und die Idee ist, es abzurufen wie:
iFace& iface = getIface();
Type& type = iface.getType();
Ich mache jedoch gelegentlich einen Fehler und schreibe:
Type type = iface.getType();
Welche kopiert nach Wert, was ich vermeiden möchte. Wenn ich jedoch solche Fehler mache, gibt der Compiler keine Warnung aus, weil seine legale Syntax. Ich möchte dafür einen Kompilierungs-Zeitfehler auslösen, Frage Was sind meine Alternativen?
Ich habe darüber nachgedacht, einen Kopierkonstruktor zu deklarieren, ihn jedoch nirgendwo definiere, was einen Link-Zeit-Fehler verursachte, wenn er verwendet wird, aber dann kann ich nicht in der Lage sein, den Kopierkonstruktor in zu verwenden IRGENDEIN Situation, die weniger als deaktiviert ist
Lösung
Machen Sie IFACE nicht kopierbar, indem Sie den Kopierkonstruktor und den Zuordnungsbetreiber in "privat" stellen. Geben Sie dann eine explizite Kopiermethode an.
class Type {
public:
virtual Copy(Type& dest) = 0;
private:
Type (const Type &) {assert(false)}
Type & operator=(const Type &) {assert(false)}
}
Sie können auch verwenden Steigern Sie nicht kopierbar das Gleiche tun (es ist wie oben implementiert).
Wenn Sie also Ihren Code kopieren möchten, würden Sie dies tun
Type& type = iface.getType();
Type typeCpy;
type.Copy(typeCpy);
Abgesehen davon - ich würde hinzufügen, dass Sie sicher sind, dass der Optimierer die temporäre Kopie für Sie nicht beseitigt, wenn Sie dies aufgrund von Leistungsbedenken tun?
Andere Tipps
Die Rückgabe eines Zeigers scheint hier vernünftig zu sein, aber wenn Sie sich Sorgen machen, können Sie einen Wrapper um die Referenz zurückgeben.
struct Class {
struct Ref {
Ref(Class& c_) : c(c_) { }
Class Clone() { return c; }
// overload -> to provide access to c
private:
Class& c;
};
};
Die ursprüngliche Klasse kann wie gewohnt kopieren, aber die Referenz, die Sie explizit machen müssen. Ich bin nicht begeistert von der Idee (ich würde weniger an einen Benutzer denken, der nicht bemerkte, wie die Kopie der Semantik funktioniert, als einer, der versehentlich an einem dieser zu lange an einer davon hielt), aber theoretisch ist es machbar.