0

簡単に言えば、私は次のようなものを持っています:

template < int TSize >
class Table
{
public:
    void someInterface();

private:

    int array[TSize];
};


template < int TSize >
class SomeBigWrap
{
    SomeBigWrap() : table(), stuff(&table) {}
    Table<Tsize> table;

    OtherStuff_1 stuff;
};

class OtherStuff_1
{

    OtherStuff_1( Table * p) : pTable(p) {}
    const Table * pTable;

    void someFnc()
    {
        pTable->someInterface();
    }
};

クラス OtherSuff_1 には、テーブルへのポインターとそのインターフェイスへのアクセスが必要です。しかし、テンプレート クラスへのポインタを作成することはできません。

OtherStuff をテンプレートにしたり、仮想関数を使用したりせずに、SomeBigWrap の現在のインスタンスのテーブルのタイプを OtherStuff に「渡す」方法はあるのでしょうか。

インターフェイスは配列とやり取りする必要があるため、1 つの ITable からすべてのテーブルを継承することはできません (仮想関数の使用を避けようとしています)。

他の方法はありますか?ダックタイピングの何らかの形でしょうか?または、デザインを完全に再考する必要がありますか?

4

3 に答える 3

0

Tableの非テンプレート基本クラスを作成し、その基本クラスにanint *とasize_tを指定すると、テンプレートのコンストラクターは、基本ポインターを配列に割り当て、配列のサイズをサイズ変数に割り当てることができます。Table<TSize>次に、ある種の動的配列のように見えるの基本クラスへのポインタを渡すことができます。

実際、私は基本クラスを可能な限りベクトルにミラーリングさせます。

サンプルコード:

#include <iostream>

class TableBase {
public:
    typedef int value_type;
    typedef value_type* pointer;
    typedef value_type& reference;
    typedef pointer iterator;
    typedef const pointer const_iterator;
    typedef size_t size_type;

    TableBase(pointer table, size_type size) : m_array(table), m_size(size)
    {}
    iterator begin() const
    {
        return m_array;
    }
    iterator end() const
    {
        return m_array + m_size;
    }
    size_t size() const
    {
        return m_size;
    }
private:
    pointer   m_array;
    size_type m_size;
};

template<size_t TSize>
class Table: public TableBase
{
public:
    Table() : TableBase(array, TSize)
    {
        for(size_t i=0; i<TSize; ++i)
            array[i] = i;
    }

private:
    int array[TSize];
};

int main()
{
    Table<16> t;

    TableBase *tp = &t;

    for( TableBase::iterator i = tp->begin(); i != tp->end(); ++i ) {
        std::cout << *i << ',';
    }
    std::cout << std::endl;
    return 0;
}
于 2012-11-16T23:47:28.677 に答える
0

残念ながら、できることはあまりなく、おそらく再設計するか、テンプレートまたは仮想を使用する必要があります. とにかく、ここにいくつかのわずかな変更があります:

ポインターをまったく保存せず、代わりに各関数の引数として渡すことを検討する場合があります。

class OtherStuff_1
{

    template<int TSize>
    void someFnc(const Table<TSize> * pTable)
    {
        pTable->someInterface();
    }
};

ネストされたクラスが機能する可能性があります:

template < int TSize >
class SomeBigWrap
{
    class OtherStuff_1
    {

        OtherStuff_1( Table * p) : pTable(p) {}
        const Table<TSize> * pTable;

        void someFnc()
        {
            pTable->someInterface();
        }
    };  
    SomeBigWrap() : table(), stuff(&table) {}
    Table<Tsize> table;

    OtherStuff_1 stuff;
};

推奨されていないものを使用することもできますvoid*

于 2012-11-16T23:46:33.213 に答える
0

テンプレートを使用する場合は、テンプレート引数を指定する必要があります。

OtherStuff_1( Table<SomeSize> * p) : pTable(p) {}
const Table<SomeSize> * pTable;

おそらくそのように定義したかったでしょう

template <int TSize>
class OtherStuff_1
{
    OtherStuff_1( Table<TSize> * p) : pTable(p) {}
    const Table<TSize> * pTable;

    void someFnc()
    {
        pTable->someInterface();
    }
};

...そしてそれを次のように使用しSomeBigWrapます

OtherStuff_1<TSize> stuff;
于 2012-11-16T23:46:45.113 に答える