1

基本的にC++FAQから、私は次のことを学びました。

仮想関数を使用すると、派生クラスで基本クラスによって提供される実装を置き換えることができます。コンパイラーは、オブジェクトが派生ポインターではなくベースポインターによってアクセスされる場合でも、問題のオブジェクトが実際に派生クラスのものである場合は常に、置換が常に呼び出されるようにします。これにより、ユーザーが派生クラスについて知らなくても、基本クラスのアルゴリズムを派生クラスで置き換えることができます。

ただし、テンプレートを使用すると、これは正しくなくなります。

別のテンプレートクラスから派生したテンプレートクラスが必要です。その後、基本テンプレートクラスに仮想関数を含めることは意味がないことに気付きました。周りを調べてみると、型消去と呼ばれるジェネリックプログラミングのポリモーフィズムの制限を克服する手法があることがわかりました。

私が読んだ例とチュートリアルは、私のニーズとはほとんど関係がありません。また、型消去の概念を正しく理解したかどうかもわかりません。初心者なので、私は単に次のことを行う必要があります。

template <typename T>
class Foo
{
public:
    virtual void doX(){cout<<"doX from Foo"<<endl;}
};

template <typename T>
class Bar : public Foo<T>
{
public:
    void doX(){cout<<"doX from Bar"<<endl;}
};

と、

Foo<int>* p;
Foo<int> i;
i.doX();           // "doX from Foo", it's ok
Bar<int> j;
j.doX();           // "doX from Bar", it's ok
p=&i;
p->doX();          // should be "doX from Foo", it's ok
p=&j;
p->doX();          // I expect "doX from Bar", but it's "doX from Foo"

編集: 私の質問は、上記の動作を実装する方法ですか?テンプレートがない場合は、期待どおりに機能します。一般のクラスでも同じことが必要です。

簡単に言えば、私は基本クラスを持っていBます。これはテンプレートクラスです。仮想機能があります。また、そのサブクラスもBテンプレートクラスであり、の動作を再実装する必要があります B(どういうわけかの仮想関数を実装しますB)。

EDIT2:タイトルを編集しました。-std=c++0xコードに必要なためstd::thread、 フラグを使用してg++4.6.3コンパイラでコードをコンパイルしていましstd::unique_ptrた。驚いたことに、-std=c++0x上記のコードを削除すると、期待どおりに機能します。また、g ++ 4.7を試しましたが、2011年と2003年の両方の標準で問題はありませんでした。

4

2 に答える 2

0

pはiポインタに割り当てられており、iはFooのタイプであるため、機能しません。基本クラス関数を使用しています。基本クラス関数を純粋仮想にする必要があります(関数= 0の最後に追加することにより)。その後、それは動作するはずです。

編集:私はそれがあなたによってOKとしてチェックされたことに気づかなかった、それはエラーだろうと思った。msvcコンパイラを使用して自分でコードを試しましたが、意図したとおりに機能しました。

于 2012-07-04T18:16:08.567 に答える
-1

関数doXは仮想ではないためです。派生クラスでは、オーバーロードではなく関数doXを非表示にするため、動的多態性は機能しません。

編集。
このような場合、-std = c ++ 0xフラグを使用すると、GCC4.6.3にバグがあります。
編集2。
おそらくGCC4.6.3にはそのようなバグはなく、問題はTSコンパイラにあります。

于 2012-07-04T18:03:27.470 に答える