Мы используем стороннюю библиотеку для управления специализированной PCI-картой. Поставщик выпустил новую карту, которая использует новый класс для управления им, но новый класс имеет те же методы, что и старый.
Если бы писал сам, я бы создал базовый класс, чтобы у нас мог быть один набор кода, использующий указатель базового класса на производный объект, но мы не можем использовать эту стороннюю библиотеку.
Я думаю, что это случай для mixin , но я не уверен. Код ниже показывает ситуацию.
Переопределение каждого метода в классе шаблона возможно, но в APIClass1
и APIClass2
существует множество методов. (методы имеют одинаковое имя и подпись). Я имею в виду что-то вроде: 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’
}
РЕДАКТИРОВАТЬ I
По предложению StoryTeller, я почти все заработал, поместив чисто базовые функции в базовый класс. Новая проблема заключается в том, что некоторые функции имеют разные подписи между APIClass1
и APIClass2
.
В приведенном ниже примере мы имеем 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;
};