Как я могу создать класс C для выполнения одинаковых вычислений на основе разных похожих классов?

#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();