2012-04-10 8 views
0

私はスレッドベースクラスを作成するために使用したLinux Self Helpオフサイトコピースレッドクラスのわずかに変更されたバージョンがありますスレッドからオーバーロードされたメンバーが呼び出されないのはなぜですか?

class Item : public Thread 

:I 2つのスレッドクラスを有する

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

class Product : public Thread 

class Itemこのスレッドを関数のコンストラクタから開始します。このクラスは、pthreadスレッドを作成するためのスレッドを作成するにはをpvArgとし、class Productはプログラム実行中に後でスレッドを作成します。

今のところ、class Itemは問題ありません。 run関数が呼び出され、正しく処理されます。

pure virtual method called 

どちらのクラスがrunメソッドをオーバーロードと同じ実装を持っていますが、一つはと呼ばれ、他ではありません:class Productは後で同じ関数を呼び出すときしかし、私が得ます。

なぜ私は突然pure virtual method called例外を受け取りますか?

ありがとうございました。

更新: class Itemは異なっているのcppファイルにstatic Item item;として宣言し、唯一のものがあるclass ProductItemのでれます。 class Productは通常のオブジェクトのように使用されます。私がclass Productと同じことをしてもうまくいきます。

+0

'Product'は' Item'から派生していないのですか?それはエラーを説明するでしょう。 – modelnine

+0

@PlasmaHH - 例外は、通常呼び出されるクラスから来ています。 'Item'のctorからの呼び出しが正しく機能しています。 – user626201

+0

@modelnine - そうではありませんが、それらははっきりと異なるクラスです。ヘッダーインクルード(スレッドヘッダー以外)にも接続がありません。 – user626201

答えて

0

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

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

1

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

0

アイテムと商品は次のとおりです。public Threadは、コンストラクタ内で仮想関数(それ自身)を呼び出します。コンストラクタ内では、vtableはまだ完全にはセットアップされていません(初期化されている各基本クラスに依存するため)、未定義の動作が発生します。

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

+0

@phresnel:*純粋な仮想関数を呼び出すことは禁止されています。コンストラクタから非純粋な関数を呼び出すことはよく定義されており、時には妥当なものになることがあります。 –

+0

@MikeSeymour:どういうわけか、私は実際に「純粋」なのですが、読んでいる間に無意識のジャグリングされた言葉があまりにも多いと思います。 –

関連する問題