0

私は本当にひどく設計されたプロジェクトに取り組んでおり、このデータ構造に出くわしました:

class OldBagOfData 
{
public:
    std::vector< BaseClass* > baseDatas;
    std::vector< Derived1* > derived1Datas;
    std::vector< Derived2* > derived2Datas;
    std::vector< Derived3* > derived3Datas;
    std::vector< Derived4* > derived4Datas;

}

クラスを更新する方法は、非常に多くの if/else 条件 (数十) を使用しており、データを読み取るだけであるにもかかわらず、メンバーは変更可能です (さらに、インスタンスではなくポインターを使用しています)。

汎用関数とテンプレートを使用してコードを単純化しました。

class CurrentBagOfData 
{
private:
    std::vector< BaseClass* > genericContainer;

    Template< typename DataType>
    std::vector< DataType* > getData( datatype IDtype);

public:
    std::vector< BaseClass* > getbaseDatas(); /* = getData<Base>("base") */
    std::vector< Derived1* > getDerived1Datas(); /* = getData<Derived1>("derived1") */
    std::vector< Derived2* > getDerived2Datas(); /* = getData<Derived2>("derived2") */
    std::vector< Derived3* > getDerived3Datas(); /* = getData<Derived3>("derived3") */
    std::vector< Derived4* > getDerived4Datas(); /* = getData<Derived4>("derived4") */

}

ただし、データを読み取って新しい入力をキューに入れるだけなので、 iterators を使用したいと思います:

// This loop is forbidden because obod.getDerived1Datas() is a temporary object
for( std::vector<Derived1*>::iterator it = obod.getDerived1Datas().begin();
                                         it != obod.getDerived1Datas().end(); i++)
{
  /* processing *it */
}

//What I want to do :
for( std::vector<Derived1*>::iteratorDerived1 it = obod.begin(); it != obod.end(); i++)
{
  // it iterate over every Derived1 datas in the generic container
  /* processing *it */
}

std::vector::iteratorDerivedX を作成するにはどうすればよいですか? 私のデザインに関するその他のアドバイスは大歓迎です。

4

3 に答える 3

1

for ループの前に関数呼び出しの戻りを保持できます。

また、繰り返しごとに end() メソッドを呼び出しているため、コストがかかる可能性があります。

また、イテレータの場合、pos インクリメントはプリ インクリメンタよりもコストがかかります。

std::vector<Derived1*> tmp = obod.getDerived1Datas();
for( std::vector<Derived1*>::iterator it = tmp.begin(), ed = tmp.end(); it != ed; ++i)
{
  /* processing *it */
}
于 2013-04-04T11:17:35.970 に答える
0

テンプレート化されたイテレータを使用する方法を見つけました。残念ながら、それは多くのオーバーヘッドを追加するので、私はそれを使用するかどうか確信が持てません:

#include <iostream>
#include <vector>

typedef std::string datatype ;

class BaseClass{
public:
    BaseClass():type("base"){}
    datatype type;

};

class Derived1 : public BaseClass{
public:
    Derived1(){ type= "derived1"; }
};
class Derived2 : public BaseClass{
public:
    Derived2(){ type ="derived2"; }
};
class Derived3 : public BaseClass{
public:
    Derived3(){ type ="derived3"; }
};
class Derived4 : public BaseClass{
public:
    Derived4(){ type ="derived4"; }
};


class CurrentBagOfData 
{
private:


    template< typename DataType>
    std::vector< DataType* > getData( datatype IDtype)
    {
        std::vector< DataType* > output;
        for(int i=0; i< genericContainer.size(); i++)
        {
            if(genericContainer[i]->type == IDtype)
            {
                output.push_back( (DataType*) genericContainer[i]);
            }

        }
        return output;
    }

public:

    // Begin of the specialized container
    template< class DataType>
    std::vector< BaseClass* >::iterator begin()
    {
        std::vector< BaseClass* >::iterator it = genericContainer.begin();


        datatype type = DataType().type;
        while( it != genericContainer.end() && (*it)->type != type   )
        {
            it++;
        }

        return it;

    }

    // End of the specialized container
    template< class DataType>
    std::vector< BaseClass* >::iterator end()
    {
        std::vector< BaseClass* >::iterator it = genericContainer.begin();
        std::vector< BaseClass* >::iterator output = it;

        datatype type = DataType().type;
        while( it!= genericContainer.end() )
        {
            it++;


            if( it!= genericContainer.end() && (*it)->type == type )
            {

                output = it;
            }

        }



        return output;

    }


    // Iterate over a certain type of elements in the container
    template< class DataType>
    void gen( std::vector<BaseClass*>::iterator &it)
    {
        const std::vector< BaseClass* >::iterator e =  this->genericContainer.end();

        // Mandatory increment
        if(it!= e )
            it++;

        // Loop until next DataType elem
        datatype type = DataType().type;
        while( it!= e && (*it)->type != type   )
        {
            it++;
        }

    }


    std::vector< BaseClass* > getbaseDatas(){ return getData<BaseClass>("base"); }
    std::vector< Derived1* > getDerived1Datas(){ return getData<Derived1>("derived1"); }
    std::vector< Derived2* > getDerived2Datas(){ return getData<Derived2>("derived2"); }
    std::vector< Derived3* > getDerived3Datas(){ return getData<Derived3>("derived3"); }
    std::vector< Derived4* > getDerived4Datas(){ return getData<Derived4>("derived4"); }


    std::vector< BaseClass* > genericContainer;






};



int main()
{
    // Object
    CurrentBagOfData cbod;

    cbod.genericContainer.push_back(new(BaseClass));
    cbod.genericContainer.push_back(new(Derived1));
    cbod.genericContainer.push_back(new(Derived3));
    cbod.genericContainer.push_back(new(Derived2));
    cbod.genericContainer.push_back(new(Derived1));
    cbod.genericContainer.push_back(new(Derived4));
    cbod.genericContainer.push_back(new(Derived3));
    cbod.genericContainer.push_back(new(Derived3));

    // Loop on Derived4 object, using the original method
    std::vector< Derived4* > o = cbod.getDerived4Datas();
    for (int i=0; i < o.size(); i++ )
    {
        std::cout << o[i]->type << std::endl;
    }
    std::cout << std::endl;

    // Loop on Derived3 objects, with custom iterators.
    std::vector< BaseClass* >::iterator it;
    for( it = cbod.begin< Derived3 >(); it <= cbod.end< Derived3 >(); cbod.gen< Derived3 >(it) )
    {
        std::cout << (*it)->type << std::endl;
    }

}
于 2013-05-14T14:50:24.530 に答える