1

定義済みの間隔でStart仮想を実行するスレッドを開始するメソッドを持つクラスがあります。ThreadFunctionメソッドはイベントを設定し、スレッドが終了するまで (スレッド ハンドルStopの a によって) 待機します。WaitForSingleObject

のデストラクタでMyThreadStopメソッドを呼び出します。そのため、インスタンスを削除するたびに、削除が戻る前にスレッドが停止していると確信しています。

class MyThread
{
    void Start();
    void Stop();
    ~MyThread() { Stop(); }
    virtual VOID ThreadFunction() { }
};

次に、から派生するクラスがありますMyThread

class A : MyThread
{
    virtual VOID ThreadFunction()
    {
        for (int i = 0; i < 1000; i++)
            TestFunction();
    }

    void TestFunction() { // Do something }
};

次のコードを検討してください。

A a = new A();
a->Start();
delete a;

問題は、正しいデストラクタを呼び出す前にdelete a、最初にデストラクタを呼び出すことです。そのため、スレッドが で を実行していた場合、メソッドはが破棄された後に呼び出されます。これにより、破壊されたインスタンスを呼び出すと、アクセス違反が発生する可能性があります。AMyThreadfor-loopThreadFunctionStopaThreadFunctionTestFunction

解決策は、次のように、メソッドclass Aを呼び出すデストラクタを追加することです。Stop

class A : MyThread
{
    ~A()
   {
       Stop();
   }
}

しかし、私は複数の継承されたクラスを含むより複雑なクラス階層を持っているため、これはStop各デストラクタでメソッドを呼び出す必要があることを意味し、その結果、削除する必要がある 1 つのインスタンスだけに対して Stop メソッドが何度も呼び出されることになります。 .

この問題に取り組む他の方法はありますか?

4

2 に答える 2

1

Rolle と R. Martinho Fernandes が示唆したように、私は 2 つの懸念事項を分離する必要がありました。

class MyThreadその責任は、スレッドの存続期間ではなく、実行するコードに限定される必要があるため、それ自体を開始または停止しないでください。

したがって、解決策は、スレッドの存続期間を担当する他のクラス (スレッドを開始した同じクラス) からスレッドを停止することでした。

于 2012-08-17T14:38:44.263 に答える
1

MyThread のデストラクタは「仮想」として定義する必要があります。

class A{
public:
    A(){cout<<"A"<<endl;}
    virtual ~A(){cout<<"~A"<<endl;}
};

class B : public A{ 
public:
    B(){cout<<"B"<<endl;}
    ~B(){cout<<"~B"<<endl;}
};

int main(){
    A* b = new B();
    cout<<"do something"<<endl;
    delete b;
    b = NULL;
    return 0;
}

結果は次のとおりです: A B 何かをする ~B ~A

仮想を使用しない場合、結果は次のようになります: A B 何かを行う ~A

于 2012-08-09T09:41:00.960 に答える