1

Function1 は、リストに追加できるように (void*) に変換される任意の型 T で呼び出すことができますが、これにより、元のポインター型が失われます (すべてに対して 1 つを作成することはできないため、1 つのリンクリストに tham を格納する必要はありません)。可能なタイプ)。したがって、どういうわけか、ポインターのタイプも保存する必要があります。C ++を使用して実行できないことはわかっています。誰かが代替ソリューションを提案できますか?

class MyClass
{

    template<class T>
    void function1(T* arg1)
    {
        myList.add((void*)arg);
    }

    void function2()
    {
        for(int i = 0; i < myList.size(); i++)
        {
            myList.get(i);
            //restore the original pointer type
        }
    }

    STLinkedlist<void*> myList;
}
4

5 に答える 5

7

この種の問題を処理する通常の方法は、パブリック インターフェイスを使用することです。C++ では、これは継承によって行われます。これは、完全なクラス/インターフェイス階層があまりにも多くのコード/ランタイム オーバーヘッドを提供する制約のある状況では特に、ドラッグになる可能性があります。

Boost.Variantが付属しています。これにより、同じオブジェクトを使用して異なる型を格納できます。さらに自由が必要な場合は、Boost.Anyを使用してください。比較については、たとえばこちらを参照してください。

一日の終わりに (または、遅かれ早かれ)、この問題が発生しないように、別の方法を試してみます。最終的にはそれだけの価値があるかもしれません。

于 2013-06-03T12:32:55.697 に答える
6

void* になって型情報を失った場合、それはなくなってしまいます。ただ復元することはできません。

したがって、ポインタとともに追加情報を保存してから、分岐コードを使用してキャスト バックするか、設計を駆動して損失を回避する必要があります。

あなたのケースは、あなたが本当に望んでいることをしていないのではないかとかなり疑わしいです。

より一般的なケースは、多態的なコレクションが必要な場合です。それはどんな種類のポインタも保存しませんが、同じ階層に属するものです。Collection には Base* ポインターがあり、Base のインターフェイスを介してオブジェクトを使用でき、すべてプログラマーの操作なしで適切な仮想関数を呼び出すことができます。また、本当に元の型にキャストする必要がある場合は、dynamic_cast を介して安全に行うことができます。または、基本インターフェースに型情報のサポートを追加します。

于 2013-06-03T12:29:50.727 に答える
3

Function1 は、リストに追加できるように (void*) に変換される任意の型 T で呼び出すことができますが、これにより、元のポインター型が失われます (すべてに対して 1 つを作成することはできないため、1 つのリンクリストに tham を格納する必要はありません)。可能なタイプ)。

あなたはXYの問題を抱えています。解決策は、void* へのポインターを減衰させず、型情報を格納することです。

考えられるすべてのタイプのタイプを作成するだけです。つまり、テンプレート タイプを作成します。「すべてのオブジェクトの型」の抽象インターフェイスを定義する必要があります。次に、このインターフェイスを実装するテンプレート クラスを定義します。これは、型によって特定されます。最後に、受け取った型のポインターでカスタム型のインスタンスを作成し、それらを基本クラス ポインター (基本クラスはインターフェイス定義) によって格納します。

つまり、機能は既に boost::any または boost::variant に実装されているため (これらのいずれかを選択する必要があります)、(通常) これを実装する必要はまったくありません。

于 2013-06-03T12:41:35.620 に答える