2

これらのクラスがあるとします:

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 を使用し続けて (必要に応じて「アンパックされた」参照に属性を付けることができるように)、このパックされた構造を作成するより良い方法を知っていますか?

アップデート

engineno-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!
4

2 に答える 2

1

insideweak_ptrの代わりに使用することを検討してください。参照カウントには寄与しませんが、必要に応じて に変換できます。shared_ptrstruct Carshared_ptr

于 2010-12-14T12:23:53.370 に答える
0
void nop(Engine*) { /* do nothing */ }

packed->car.engine = shared_ptr<Engine>(&packed->engine, nop);

説明: このコードは、エンジンを所有していると考える shared_ptr を作成しますが、実際には別の参照カウンターを持ち、deleter が呼び出されても何もしません。

于 2010-12-14T12:14:52.397 に答える