How to properly manage two containers of different types in a class?

I have the following (kinda pseudo) code that processes 2 containers of two different (but somewhat similar) types, and I hate using these duplicates to add and remove (as well as 2 search functions in my real code)

class PureAbstractClass
{
public:
    virtual char Func() = 0;
}

class PureOpt1 : PureAbstract
{
public:
    virtual int FOption1(A, B, C) = 0; // Notice 'C'
}

class PureOpt2 : PureAbstract
{
public:
    virtual int FOption2(A, B, D) = 0; // Notice 'D'
}

class Handler
{
public:
    void Add(PureOpt1* arg) { v1.add(arg); }
    void Add(PureOpt2* arg) { v2.add(arg); }

    // This is implemented using lambda
    // Sorry for LINQ syntax, lambdas are too long for pseudo code
    void Del1(char c) { arg = v1.find(obj => obj->Func() == c); v1.del(arg); }
    void Del2(char c) { arg = v2.find(obj => obj->Func() == c); v2.del(arg); }

    void Process(ch, A, B, C, D)
    {
        o1 = v1.Find(obj => obj->Func() == ch);

        if( null == o1 )
        {
             o2 = v2.Find(obj => obj->Func() == ch);
             if( null == o2 )
             {
                  DoSomething();
             }
             else
             {
                  o2->FOption2(A, B, D);
             }
        }
        else
        {
             o1->FOption1(A, B, C);
        }

    }

private:
    vector<PureOpt1*> v1;
    vector<PureOpt2*> v2;
}

Availability Handleris a template class impossible due to Process().

Is there a better way to implement this type of code?

+4
source share
2 answers

How to properly manage two containers of different types in a class?

The answer is used only for 1 container.

The simplest solution would be to have a pure life method in a base class:

class PureAbstractClass
{
public:
    virtual char Func() = 0;
    virtual int FOption(A, B, C, D) = 0; 
}

FOption() , . , . - , , . solution ( , ). dynamic_cast, :

PureAbstractClass *o = find( ... );
if( !o ) {
   DoSomething();
   return;
}
if( PureOpt1 *po1 = dynamic_cast<PureOpt1 *>( o ) )
     po1->FOption1( A, B, C );
else {
    if( PureOpt2 *po2 = dynamic_cast<PureOpt2 *>( o ) )
        po2->FOption2( A, B, D );
    else
       // something wrong object is not PureOpt1 nor PureOpt2
}

: FOption1() FOption2() . .

boost::variant , , .

+3

, FOption1/2 int Func ( const ). . , C D . Func .

0

Source: https://habr.com/ru/post/1665266/


All Articles