簡體   English   中英

如何在一個類中正確管理2個不同類型的容器?

[英]How to correctly manage 2 containers of different types in a class?

我有以下(kinda偽)代碼,該代碼可處理2個不同(但有些相似)類型的2個容器,並且我討厭將這些重復添加和刪除(在我的真實代碼中還有2個搜索功能)

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;
}

由於Process() Handler作為模板類是不可能的。

有沒有更正確的方法來實現這種代碼?

如何在一個類中正確管理2個不同類型的容器?

答案是僅使用1個容器。

最簡單的解決方案是在基類中具有純生命方法:

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

然后兩個子級都覆蓋FOption()並忽略它們不需要的參數。 可能有更好的解決方案,但您沒有提供足夠的信息。 您的解決方案-將它們保存在2個單獨的容器中可能是最糟糕的。 如您所見,您的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和visitor模式,在這種情況下,您也不需要繼承,但是可以使代碼通用。

如果可能,請將FOption1 / 2設置為int Func(Data const&data)。 然后,您創建數據並將其傳遞給它。 數據可以具有四個不同的信息,其中C和D是可選的。 然后,Func的特定實現可以根據需要處理該數據

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM