0

私が何を意味するかを示しましょう。

#include <functional>
#include <iostream>

class MyClass
{
private:
    int number;
public:
    MyClass()
    {
        number = 0;
    }

    void printNumber()
    {
        std::cout << "number is " << number << std::endl;
        number++;
    }
};

int main()
{
    std::shared_ptr<MyClass> obj = std::make_shared<MyClass>();
    auto function = std::bind(&MyClass::printNumber, obj);

    function();

    // This deallocates the smart pointer.
    obj.reset();

    // This shouldn't work, since the object does not exist anymore.
    function();

    return 0;
}

これは以下を出力します:

number is 0
number is 1

「function()」を「obj->printNumber()」に置き換えて、通常のように関数を呼び出すと、出力は次のようになります。

number is 0
Segmentation fault: 11

あなたがそれを期待するのと同じように。

だから私の質問は、オブジェクトの割り当てが解除されたときに関数を呼び出すことができないことを確認する方法があるかどうかです? これは、スマート ポインターの使用とは関係ありません。通常のポインターと同じように機能します。

4

3 に答える 3

3

std::function points有効なオブジェクトのメンバーかどうかを確認する方法はありますか?

std::function「オブジェクトのメンバー」を指すのではなく、Callableをカプセル化します。それをオブジェクトにバインドすると、別の呼び出し可能なオブジェクト (実際には未指定の型) を取得し、std::function

私の質問は、オブジェクトの割り当てが解除されたときに関数を呼び出すことができないことを確認する方法があるかどうかです。

いいえ、仕方がありません。しかし、ecatmur が指摘したように、std::bindそれは引数であるため、あなたの例では問題ありません。

于 2014-08-20T17:07:13.447 に答える
0

「これはスマート ポインターの使用とは関係ありません。通常のポインターと同じように機能します。」このステートメントは正しくありません。スマート ポインターを使用した obj->printNumber() は、オブジェクトが破棄されたからではなく、共有ポインターのこの特定のインスタンスがobj有効なオブジェクトを指していないために失敗します。生のポインターでこれを行おうとすると、次のようになります。

MyClass *obj = new MyClass;
auto function = std::bind(&MyClass::printNumber, obj);

function();

delete obj;

// This will have UB
function();

破棄とメモリの割り当て解除後にオブジェクトを使用すると、まったく異なる状況 (未定義の動作) が発生します。

C++ では、生のポインターが有効なオブジェクトを指していることを検証する方法がありません。しかし、使用できるのはstd::weak_ptr. 直接動作しないstd::bindため、ラムダまたは単純なラッパーを記述して、オブジェクトがまだ有効であることを確認することをお勧めします。

auto wrapper = []( std::weak_ptr<MyClass> wobj ) { auto obj = wobj.lock(); if( obj ) obj->printNumber(); };
auto function = std::bind( wrapper, std::weak_ptr<MyClass>( obj ) );
于 2014-08-20T17:24:47.407 に答える