#c #class #inheritance
#c #класс #наследование
Вопрос:
Возможно, мое название немного расплывчатое, и это потому, что я не знаю точно, как это называется, чего я хочу достичь (поэтому вы можете предложить улучшение названия). Однако посмотрите на следующий пример кода.
У меня есть несколько классов (aSumSub, bSumSub, … xSumSub), что они похожи. На самом деле они имеют точно такие же переменные и функции, но реализованы по-разному.
Я хочу создать другой класс (SumSub), который будет выполнять некоторые вычисления на основе любого из этих классов xSumSub. Функциями, выполняющими эти дополнительные вычисления, являются results1, results2 .. и т.д.
Как я могу реализовать это эффективным способом? Самым простым способом было бы скопировать класс SumSub, присвоить ему другое имя и просто изменить тип переменной «x» и конструктора. Однако для этого мне потребовалось бы копировать несколько сотен строк кода снова и снова, просто для изменения пары строк, чтобы сделать его совместимым со всеми функциями xSumSub.
Должен быть более чистый способ!
#include <iostream>
using namespace std;
// Class a
// I am not allowed to modify this
class aSumSub {
public:
int sum(){
return 10 1;
}
int sub(){
return 10-1;
}
};
// Class b which has EXACTLY the same types of functions and variables as Class a has, but it's different implementation.
// I am not allowed to modify this
class bSumSub {
public:
int sum(){
return 20 1;
}
int sub(){
return 20-1;
}
};
// Here we could have class cSumSub, ..... xSumSub etc.
// Not allowed to modify either.
// The following Class SumSub is doing some calculations that they are based on the output of the functions of the xSumSub classes.
// That's the one I want to create
class SumSub {
public:
bSumSub *x; // <- How can I make this variable to be either of type bSumSub or aSumSub or xSumSub?
SumSub(bSumSub *ssclass){ // And consequently, how can I have the constructor accepting either bSumSub or a aSumSub or xSumSub?
x = ssclass;
}
// The rest of the functions should't need any modification
// because we know that *x will always have the same functions and the same types will always be returned.
void result1(){
cout << x->sum() << endl;
}
void result2(){
cout << x->sub() << endl;
}
void result3(){
cout << x->sum()-x->sub() << endl;
}
void result4(){
cout << x->sum() x->sub() << endl;
}
};
int main(){
aSumSub as;
bSumSub bs;
cout << "as.sum=" << as.sum() << endl;
cout << "bs.sum=" << bs.sum() << endl;
SumSub ss1(amp;bs);
cout << endl << "SumSub" << endl;
ss1.result1();
ss1.result2();
ss1.result3();
ss1.result4();
// I would like to be able to do the following as well
//SumSub ss2(amp;as);
//cout << endl << "SumSub" << endl;
//ss2.result();
//ss2.result1();
//ss2.result2();
//ss2.result3();
//ss2.result4();
return 0;
}
Ответ №1:
Используйте шаблоны. Вот шаблон SumSub
.
template <typename T> class SumSub {
public:
T *x;
SumSub(T *ssclass){
x = ssclass;
}
void result1(){
cout << x->sum() << endl;
}
void result2(){
cout << x->sub() << endl;
}
void result3(){
cout << x->sum()-x->sub() << endl;
}
void result4(){
cout << x->sum() x->sub() << endl;
}
};
Ответ №2:
Используйте шаблон:
template <typename BumStub>
struct SumSub
{
using type = BumStub;
type * x;
SumSub(type * p) : x(p) { }
void result1() { std::cout << x->sum() << std::endl; }
// etc.
}
Использование:
aSumSub as;
SumSub<aSumSub> ss1(amp;as);
ss1.result1();