将两个类合并为通用基类(模板?mixin?)

时间:2018-07-01 07:38:19

标签: c++ templates mixins

我们使用第三方库来控制专用的PCI卡。供应商发布了一种使用新类来控制它的新卡,但是新类具有与旧类相同的方法。

如果要编写自己的代码,我将创建一个基类,这样我们就可以使用指向派生对象的基类指针来编写一组代码,但不能使用该第三方库。

我认为这是 mixin 的一种情况,但我不确定。下面的代码显示了这种情况。

可以重新定义模板类中的每个方法,但是APIClass1APIClass2中有很多方法。 (这些方法具有相同的名称和签名)。我的意思是:void one() { TBase::one(); }

C ++中有没有一种方法可以做到这一点而又无需重复很多代码?

#include <stdio.h>

class APIClass1
{
public:
    void one() { printf("APIClass1 ONE\n"); }
    void two() { printf("APIClass1 TWO\n"); }
};

class APIClass2
{
public:
    void one() { printf("APIClass2 ONE\n"); }
    void two() { printf("APIClass2 TWO\n"); }
};

class MasterClassBC
{ };

template <class T>
class MasterClass : public T, public MasterClassBC
{
public:
    typedef T TBase;
};

int main(int argc, char *argv[])
{
    // Use pointer to base class object
    MasterClassBC *pBc;
    if (isNewCard())
        pBc = new MasterClass<APIClass2>;
    else
        pBc = new MasterClass<APIClass1>;

    pBc->two(); // error:‘class MasterClassBC’ has no member named ‘two’
}

编辑我

根据StoryTeller的建议,通过将纯虚函数放在基类中,我几乎可以正常工作。新问题是某些功能在APIClass1APIClass2之间具有不同的签名。

在下面的示例中,我们有void three()void three(int n)

我尝试创建newThree()并在运行时调用适当的函数,但由于TBase缺少一种或另一种three方法(取决于它的专门技术),因此无法编译。

class APIClass1
{
public:
    void one() { printf("APIClass1 ONE\n"); }
    void two() { printf("APIClass1 TWO\n"); }
    void three() { printf("APIClass1 THREE\n"); }
};

class APIClass2
{
public:
    void one() { printf("APIClass2 ONE\n"); }
    void two() { printf("APIClass2 TWO\n"); }
    void three(int n) { printf("APIClass2 THREE: %d\n", n); }
};

class MasterClassBC
{
    virtual void one() = 0;
    virtual void two() = 0;
    virtual void newThree() = 0
};

template <class T>
class MasterClass : public T, public MasterClassBC
{
public:
    typedef T TBase;
    MasterClass(bool useApi1 = true) : mUseApi1(useApi1) {}

    void setTheNumber(int n) { mTheNumber = n; }

    void one() { TBase::one(); }
    void two() { TBase::two(); }

    void newThree()
    {
        if (mUseApi1)
            TBase::three();
        else
            TBase::three(mTheNumber);
    }

private:
    bool mUseApi1;
    int  mTheNumber;
};

0 个答案:

没有答案