1

I implemented a C-API for a C++ class which uses shared-pointers of other objects to access them. In my C-API I can of course only get raw pointers. So I "convert" the raw pointer in my C-API to a shared-pointer and use this then with my C++ class methods:

method(std::shared_ptr<dataType>(raw-pointer));

Now I have the problem that at the end of "method" always the shared-pointer destructor is called and it unfortunately kills the object my raw-pointer is pointing at (which I don't want). So, how can I prevent the raw-pointer from being killed?

I already tried shared-pointer functions like reset() or swap(), but they all didn't let my raw-pointer go...

bool Traffic_doStep(traffic_handle t, environment_handle e, double cycletime) {
    if (!valid(t, __FUNCTION__)) return false;
    if (!valid(e, __FUNCTION__)) return false;
    if (!valid(cycletime, __FUNCTION__)) return false;

    try {
        t->doStep(std::shared_ptr<Environment>(e), cycletime);
        return true;
    }
    catch (const std::exception& e) {
        std::cerr << e.what() << std::endl;
        return false;
    }
}

Expected result would be that the raw-pointer e is still pointing to a valid object after this function returned. Actually the raw-pointer points then to a deleted object.

4

2 に答える 2

12

ポインタをstd::shared_ptr

C++ のスマート ポインターの目的は、ライフタイムの自動管理を提供することです。を書くときstd::shared_ptr<int> ptr{raw_ptr};、期待されるのは、ptrがスコープ外になると、 が指すオブジェクトが'dさraw_ptrれるということです。deleteこれが意図されていない場合は、ポインターをスマート ポインターに配置しないでください。

したがって、アプリケーションがポインターの有効期間を管理していない場合は、生のポインターを格納してもまったく問題ありません。

関数の背後にある API を変更できない場合はstd::shared_ptr、クリーンアップが呼び出されたときにポインターに何も起こらないように、ノーオペレーションの削除関数を使用して を構築する必要があります。

try {
    std::shared_ptr<Environment> temp_ptr{e, [](int *) {}/*No-Op Deleter*/};
    t->doStep(temp_ptr, cycletime);
    return true;
}

これで問題は解決しますが、これはもちろんアンチパターンです。制御できない API 設計の制約によって強制されない限り、これを行わないでください。

于 2019-08-14T15:18:05.267 に答える