これらのクラスがあるとします:
struct Engine {
int engine_data;
};
struct Car {
shared_ptr<Engine> engine;
int car_data;
};
パフォーマンス上の理由から、メモリにぎっしりと詰め込みたいと思います (ただし、設計の柔軟性を失いたくありません)。したがって、「パックされた」構造と、新しい B インスタンスを透過的に返すファクトリを作成できます。
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;
}
問題は、参照カウントが 2 であるため、この "car" インスタンスが破棄されないことです。死ぬと、参照カウントは永遠に 1 になります。内部の shared_ptr を使用し続けて (必要に応じて「アンパックされた」参照に属性を付けることができるように)、このパックされた構造を作成するより良い方法を知っていますか?
アップデート
engine
no-op デリータを使用することもできますが、 を保持して を保持しない場合は非常に危険です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!