1

次のタイプのデータを格納するコンテナーラッパーを考え出そうとしています:bool、int、double、std::string。さらに、コンテナに格納する必要がある複雑なタイプがあります。それをFooと呼びましょう。簡単にするために、Fooにはintのリストが含まれていると言います。

私のコンテナクラスは現在、acapiから取得した醜く複雑なコンテナタイプをラップしています。コンテナ内のデータの操作が終了したら、それをAPIにコピーして戻す必要があります。ユニオンとリンクリストを使用します。このデータをたとえばstd::listにコピーすることは可能ですが、これによりパフォーマンスの問題が発生し、後日発生する可能性があります。したがって、私のコンテナクラスは、データが実際にメモリに格納される方法に依存しません。

これが私のコンテナがどのように見えるかについての簡単なアイデアです:

template <class T>
class Cont
{
public:
    Cont(ISetter<T>* setter)
        : _setter(setter)
    {
    }

    void sillyFunction(T t)
    {
        (*_setter)(t,0);
    }

private:
    ...
    ISetter<T>* _setter;
};

そこで、メモリの要点を処理するヘルパーセッタークラスを使用します。私はこれらのクラスをいくつか持っていますが、ISetterは私が何をしているのかをあなたに教えてくれます。

かなり奇妙な方法でcapiによっても保存されるFooタイプに対処するために、私は次のセッターに到達しました。繰り返しますが、これは大まかな例です。

class IFoo
{
public:
    virtual int getMember() = 0;
};

class Foo2: public IFoo
{
public:
    virtual int getMember(){ return 1;} // dummy 
};

template<typename T> class ISetter{};
template<> class ISetter<IFoo*>
{
public:
    virtual void operator()(IFoo* value, int index) = 0;
};

template<typename T> class Setter{};
template<> class Setter2<Foo2*>: public ISetter<IFoo*>
{
public:
    virtual void operator()(IFoo* value, int index)
    {
        _list[index] = dynamic_cast<Foo2*>(value);
    }

private:
    std::vector<Foo2*> _list;
};

そのため、FooをIFooというインターフェイスとして処理します。Setter2の実装は、Foosのリストのメモリ内の設定を処理します。Setter1は、以下にありませんが、醜いcapiメモリを扱います。

これらのクラスの実際のアイデアは次のとおりです。

Foo2* f = new Foo2();
ISetter<IFoo*>* setter = new Setter2<Foo2*>();
Cont<IFoo*>* container = new Cont<IFoo*>(setter);
container->sillyFunction(f); 

たとえば、intを扱うときは、代わりに次のようにします。

int i = 10;
ISetter<int>* setter = new Setter1<int>();
Cont<int>* container = new Cont<int>(setter);
container->sillyFunction(i);

ですから、私の質問は、これが良いアプローチであると思うかどうか、そしてどのような改善をお勧めするかということです。

生のポインターの代わりに共有ポインターを使用します。

4

2 に答える 2

1

C APIからメンバーデータを検索できる単一の単純なFooラッパークラスを作成し、それをコヒーレントクラスとして提示します。そのためのインターフェース、仮想関数、または継承をいじくり回す必要はありません。たった1つのクラスで十分です。

したがって、C APIの「Foo」エントリごとに、単一のFooラッパーを作成します。

次に、Cライブラリに格納されているデータの個々のインスタンスを表す単純で正常に動作するタイプがあります。

今それを取り、それをに入れてstd::vectorください。

struct Foo {
    Foo(<handle-or-pointer-to-library-data>);

    // member functions for retrieving member data from the C API
};


std::vector<int>
std::vector<bool>
std::vector<std::string>
std::vector<Foo>

私はあなたの問題を理解しているので、それは単純で効率的な解決策になるでしょう。

于 2012-09-10T13:10:10.410 に答える
1

少し変更します。このSetter仮想主義をすべてコードから削除することを検討してください。テンプレートを導入する目的の1つは、仮想主義に代わるものを用意することでした。

template <class T, class Setter>
class Cont
{
public:
    Cont(Setter setter = Setter())
        : _setter(setter)
    {
    }

    void sillyFunction(T t)
    {
        _setter(t,0);
    }

private:
    ...
    Setter _setter;
};

そしてその簡単な使用法:

template <class IType, class Type>
class Setter2_Virtual
{
public:
    void operator()(IType* value, int index)
    {
        _list[index] = dynamic_cast<Type*>(value);
    }

private:
    std::vector<Type*> _list;
};


Cont<IFoo*, Setter2_Virtual<IFoo, Foo2> > container;
container.sillyFunction(f); 

私はセッターに集中しましたが、IFoo/Fooのものでも同じことができるかもしれません。

ただのアイデア-結局のところ、それを使用する義務はありません。

于 2012-09-10T15:01:09.743 に答える