2017-10-18 4 views
1

には、以下の私が持っているとしましょう:メンバー関数はいつスコープから外れますか?

struct Foo 
{ 
    Foo() : bar([&]{ doSomething();}) 
    std::function<void(void)> bar; 
    void doSomething(){}; 
} 

を、別のスレッドはFooのインスタンスを破棄しながら、一つのスレッドが常にFooのインスタンスのバー部材を呼び出していると言うことができます。 Fooのデストラクタが最初に呼び出されたため、barへの呼び出しで無効な関数呼び出しが発生する可能性はありますか? Fooのデストラクタは、解放前にメンバ関数の呼び出しを無効にしますか?

編集: 残念ですが、もう少し具体的にすべきでしたが、バーのデストラクタが呼び出される前にdoSomethingが定義されなくなりましたか?

+0

オブジェクトにはメンバー変数が存在します。オブジェクトがない場合、メンバー変数はどのように存在しますか? –

+2

スレッドが別のスレッドを使用している間にオブジェクトを破棄しないようにするのは、あなたの責任です。 –

+0

これは、オブジェクトが自身の破壊を同期できない主な理由です。 '破棄要求'を実装したい場合、つまり、他の要求を同時に処理しながらオブジェクトを破壊するように要求することができます。これは、クラス自体ではなく、外部で同期する必要があります。 – ComicSansMS

答えて

0

メンバ関数は、オブジェクトが有効になるまで有効です。オブジェクトが破棄されると、メンバ関数も破棄され、デストラクタが呼び出されるとオブジェクトが破棄されます。したがって、デストラクタの呼び出しはメンバ関数を無効にします。また、オブジェクトの破壊後にメンバ関数を呼び出すと、未定義の動作が発生します。したがって、オブジェクトが破棄された後にメンバー関数が呼び出されていないことを確認する必要があります。

3

Fooのデストラクタが最初に呼び出されたため、barを呼び出すと無効な関数呼び出しが発生する可能性はありますか?

はい、あなたが起こらないことを確認していない限り。

Fooのデストラクタは、割り当て解除前にメンバー関数の呼び出しを無効にしますか?

はい。そのオブジェクトとそのサブオブジェクトへのすべての参照は、デストラクタが呼び出されるとすぐに無効になります。

なおメンバ関数は、あなたが持っているものとは異なるものです。あなたが持っているのは、メンバーオブジェクトである関数ラッパーです。違いは答えに何の違いもありません。

+0

明確にする:*無効にする*とは、デストラクタが起動するとすぐにメンバ関数を実行することが無効であることを意味します。言語は実際にこれを強制するものではありません。これが決して起こらないようにするのはあなたの責任です。これを正しく行なわなければ、プログラムはあなたの顔で爆破することが許されます。 – ComicSansMS

関連する問題