0

Linux Self Helpサイトからコピーしたスレッド クラスのわずかに変更されたバージョンを使用して、スレッド化基本クラスを作成しました。

class Thread
{
public:
static void *entry (void *pvArg) { Thread *pobjThread = static_cast<Thread *> (pvArg); pobjThread->run (); }
virtual void run (void) = 0;
};

私は2つのスレッドクラスを持っています:

class Item : public Thread

class Product : public Thread

class Item関数のコンストラクターからスレッドを開始し、このクラスを pthread ライブラリに追加して、プログラムの実行中に後でそのスレッドを作成するwhileとして呼び出すスレッドentryを作成します。thispvArgclass Product

問題は、正常に動作することですclass Itemrun関数が呼び出され、正しく処理されます。ただし、class Product後で同じ関数を呼び出すと、次のようになります。

pure virtual method called

どちらのクラスも、メソッドをオーバーロードして同じ実装をしていますrunが、一方が呼び出され、もう一方が呼び出されていません。

突然pure virtual method called例外が発生するのはなぜですか?

ありがとう。

更新: は cpp ファイルでa として宣言されており、1 つしかないためclass Item、異なります。通常のオブジェクトのように使用されます。私が同じことをすると、うまくいきます。class ProductItemstatic Item item;class Productclass Product

4

3 に答える 3

1

コンストラクタまたはデストラクタから仮想関数を呼び出さないでください。コードがどちらかで実行されている場合、継承チェーンは不完全であるため、仮想関数を呼び出す意味のある方法はありません。別の答えについては、コンストラクタとデストラクタからの純粋な仮想呼び出しを参照してください。

于 2012-04-10T15:32:11.617 に答える
0

Item と Product は : public Thread は、コンストラクター内で (それ自体の) 仮想関数を呼び出すことを意味します。コンストラクター内では、vtable はまだ完全に設定されていないため (初期化される各基本クラスに依存するため)、未定義の動作が発生します。

ベスト プラクティス: コンストラクター/デストラクター内から仮想関数を呼び出さないでください。コンストラクタ/デストラクタは非常にシンプルに保ち、残りの作業は init() 関数内などで行います。

于 2012-04-10T15:35:00.053 に答える
0

modelnine の指摘のおかげで、スレッドが実行される前に、問題のあるコードがオブジェクトを作成し、スレッドを開始してからオブジェクトを破棄していたことがわかりました。これは、modelnine が示したように、vtable を削除し、これが問題の原因でした。

質問のコメントでmodelnineに感謝します。

于 2012-04-10T15:36:59.480 に答える