Angenommen, ich habe diese Klassen:Wie verwaltet man shared_ptr, das auf interne Daten eines bereits referenzierten Objekts zeigt?
struct Engine {
int engine_data;
};
struct Car {
shared_ptr<Engine> engine;
int car_data;
};
Aus Performance-Gründen möchte ich in Erinnerung sie dicht gepackt machen (aber ich will nicht die Flexibilität des Designs verlieren). Also, ich kann eine „verpackt“ Struktur erstellen, und eine Fabrik, die transparent eine neue B-Instanz zurück:
struct PackedCarAndEngine {
Engine engine;
Car car;
};
shared_ptr<Car> new_Car() {
shared_ptr<PackedCarAndEngine> packed = make_shared<PackedCarAndEngine>();
// uses aliasing shared_ptr constructor
packed->car.engine = shared_ptr<Engine>(packed, &packed->engine);
// again
shared_ptr<Car> car = shared_ptr<Car>(packed, &packed->car);
return car;
}
Das Problem ist, dass diese „Auto“ Instanz wird nie zerstört werden, weil es einen Referenzzähler hat von zwei. Wenn es stirbt, wird es für immer eine Referenzzahl von eins haben. Kennen Sie eine bessere Möglichkeit, die internen shared_ptrs weiter zu verwenden (so dass ich eine "entpackte" Referenz zuweisen kann, wenn ich möchte) und trotzdem diese gepackte Struktur erstellen?
UPDATE
ich einen no-op deleter verwenden könnte, aber dann wäre es sehr gefährlich sein, wenn ich die engine
zu halten entscheiden, aber nicht die car
:
// ...
packed->car.engine = shared_ptr<Engine>(&packed->engine, do_nothing_deleter);
// ...
shared_ptr<Car> my_car = new_Car();
shared_ptr<Engine> my_engine = my_car->engine;
my_car.reset(); // Danger: engine was destroyed here!!!
cout << my_engine->engine_data; // Crash!
Warum machst du nicht einfach eine Maschine ein gerades Mitglied des Autos? Wenn Sie immer ein Auto und eine Engine als Teil desselben Objekts erstellen, bedeutet dies, dass sie dieselbe Lebensdauer haben. Auto weiß um Motor, aber nicht umgekehrt. Es sei denn, Sie planen, die gleiche Engine-Instanz zwischen verschiedenen Car-Instanzen zu teilen, würde "struct Car {Engine engine; int Auto_Daten; }; 'ein einfacheres Design sein? –
@Charles Ich habe darüber nachgedacht ... falls ich das Problem nicht einfach mit 'shared_ptr' lösen kann, werde ich auf diese Lösung zurückgreifen. In diesem Beispiel gab ich, ich habe nur eine Komposition, aber in meinem realen Design, habe ich viele Klassen auf diese Weise, in mehreren Schichten, und ich möchte die Flexibilität der Zuweisung von anderen 'Motoren kommen aus anderen Orten . –