假设我有这些课程:
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。当它死亡时,它的引用计数将永远为 1。您是否知道继续使用内部 shared_ptr 的更好方法(以便我可以根据需要将“未打包”引用归因于),并且仍然制作此打包结构?
更新
我可以使用无操作删除器,但是如果我决定保留engine
但不保留 ,那将是非常危险的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!