nach dem Lesen Effective C++ von Scott Meyers, wird die folgende Lösung:
eine Vorlage definieren, die einen faulen eva tut wertung (mit Referenzzählung):
class Obj : private lazy<Obj_data>{};
und lazy speichert die Obj_data privat hat Accessoren geschützt, eine für Modifikation, einer für den Lesezugriff.
Der Modifikator Accessor kopiert die Obj_data
bei Bedarf zuerst tief und überträgt dann den Verweis auf die Daten. Der schreibgeschützte Accessor gibt nur eine const-Referenz zurück.
Die Gesamtkosten hierfür sind die Speicherung von 2 zusätzlichen Zeigern (einen für die Daten und einen für den Zähler) und einen Zähler.
Die Umsetzung ist in etwa so:
class lazy{
protected:
lazy(const lazy&obj){lazy_copy(obj);}
//(the required constructors, operator= ...)
// accessors:
const Obj_data& data() const {return *od;}
Obj_data& mod_data() {make_private(); return *od;}
private:
void lazy_copy(const lazy& obj);
void make_private(); // this does the actual deep-copy, as late as possible.
private:
counter*;
Obj_data* od;
};
So, Lesen und ein Attribut Obj
Modifizierung geht
void Obj::method(){
cout << data().some_attribute; // simple read
mod_data().i = 10; // simple modify
const Obj_data& const_d = data(); // assignable for lots of read-outs
Obj_data& var_d = mod_data(); // assignable for lots of modifications.
}
Beachten Sie, dass Sie nur data()
in einem const
Mitglied als mod_data()
ist ein nicht verwenden können, -const Funktion in der Klasse, so ist diese Lösung völlig sicher mit wenig Overhead.
Theorie Hintergrund: das gewünschte Verhalten in der Frage ist ein Implementierungsdetail, betrifft nicht den Client. Deshalb lösen wir es durch private Vererbung.
Ich denke, Sie müssen möglicherweise eine clone() -Methode hinzufügen und tun, was Sie explizit wollen. – Caribou
Das ist es, was ich vermeiden möchte, um kaum nachverfolgbar Fehler in meinen Code zu schreiben. So einfach ist es. –
Nun, ich denke, es ist viel gefährlicher - besonders nachdem du Jobs verschoben hast und jemand neues reinkommt ... (My 2 penneth) – Caribou