Ograniczenie szablonów do typów

0

Witam mam kilka pytań, ale najpierw przedstawię treść problemu

Treść:
Oprogramować algebrę wielomianów.
Utworzyć abstrakcyjną klasę bazową zawierającą:

  • właściwości algebry wielomianów
  • operacje wprowadzania i wyprowadzania
  • konwersję z typu double oraz do typu double.
    Bazując na niej utworzyć klasę
    wielomianów oraz klasę wielomianów binarnych (współczynniki wielomianu są binarne,a dodawanie jest dodawaniem modulo 2 bez przeniesienia).

Reasumując:
Algebra - klasa bazowa abstrakcyjna

  • Wielomiany -k. pochodna od Algebry
  • WielomianyBinarne -k. pochodna od Algebry

Pytania

  1. Z racji że działania na Wielomianach i WielomianachBinarnych, w pewnych aspektach byłyby podobne, to dobrze byłoby przeładować tylko raz operator w klasie Bazowej dla danej operacji, a potem korzystać z tych operatorów w klasach pochodnych. Niestety jest to klasa Abstrakcyjna, wiec z powodów oczywistych jest to niemożliwe. Mam 2 pomysły:
    a) Wielodziedziczenie
    b) Zastosowanie szablonów funkcji operatorowych w klasie Algebra

a) Nie jestem przekonany do rozbijania jednej klasy na 2.
b) Pomysł wydaje mi się ciekawszy, tylko nie wiem czy istnieje jakis sposob aby ograniczyc szablon do 2ch klas. Raz chciałbym aby były to Wielomiany a innym razem WielomianyBinarne

template <class T>
T operator+(T skladnik)
{
  //
} 

Jeżeli jest jakieś lepsze rozwiązanie to jestem otwarty na nowe pomysły.
Pozdrawiam :)

1
darthachill napisał(a):
  1. Z racji że działania na Wielomianach i WielomianachBinarnych, w pewnych aspektach byłyby podobne, to dobrze byłoby przeładować tylko raz operator w klasie Bazowej dla danej operacji, a potem korzystać z tych operatorów w klasach pochodnych. Niestety jest to klasa Abstrakcyjna, wiec z powodów oczywistych jest to niemożliwe.

W C++ nie można tylko utworzyć obiektu klasy abstrakcyjnej, można za to z niej dziedziczyć implementację. Więc możesz zdefiniować coś w klasie bazowej i dziedziczyć to coś w klasie pochodnej.

#include <iostream>
using namespace std;

class Abstrakcyjna{
public:
    void foo(){cout << "Jestem klasy abstrakcyjnej" << endl;}
    virtual void bar() = 0;
};

class Pochodna: public Abstrakcyjna{
    int a,b;
    void bar() override{
        //Definicja funkcji wirtualnej w klasie pochodnej
        cout << "Funkcja wirtualna" << endl;
    }
};

int main(){
    //Abstrakcyjna A; // BLAD: Nie mozna utworzyc obiektu klasy abstrakcyjnej
    Pochodna B;
    B.foo();
}

Jak widzisz, można dziedziczyć implementację z klasy abstrakcyjnej. Musisz pamiętać, że w C++ klasa Abstrakcyjna to nie to samo co Interfejs w Javie

darthachill napisał(a):

b) Pomysł wydaje mi się ciekawszy, tylko nie wiem czy istnieje jakis sposob aby ograniczyc szablon do 2ch klas. Raz chciałbym aby były to Wielomiany a innym razem WielomianyBinarne

template <class T>
T operator+(T skladnik)
{
  //
} 

Jeżeli jest jakieś lepsze rozwiązanie to jestem otwarty na nowe pomysły.
Pozdrawiam :)

Nie wiem o co konkretnie pytasz. Jeśli chodzi Ci o zabronienie innym klasom używania tego szablonu: Niestety nie można wskazać konkretnych dwóch klas dla których szablon będzie działał. W tym przypadku musisz użyć static_assert albo enable_if<> , uchroni Cię to przed przypadkowym użyciem szablonu dla "złej" klasy. Powiedzmy, że tworzę szablon funkcji która ma działać tylko dla typów podstawowych:

#include <iostream>
using namespace std;

template <typename T>
void wypiszTypPodstawowy(T wartosc){
    static_assert(is_integral<T>::value, "BLAD: Typ nie jest podstawowy"); // is_integral jako test "podstawowosci typu T
    // Dalsza Implementacja
}

struct X{
    int a;
};

int main(){
    X a{1};
    wypiszTypPodstawowy(a);
}

Może również Tobie chodzić o "specjalizację" szablonu, czyli wersję szablonu napisaną specjalnie dla danego typu. W tym przypadku odsyłam tutaj: http://www.cprogramming.com/tutorial/template_specialization.html

1 użytkowników online, w tym zalogowanych: 0, gości: 1