Wywoływanie odpowiedniej funkcji w zależności od parametrów

0

Hej,

Piszę prosty algorytm genetyczny i używam w nim stworzonej przez siebie klasy oceniającej (każdemu osobnikowi w populacji daje ona tzw. fitness, czyli jak dobrze pasuje dana jednostka do wzorca), chcę przy tworzeniu obiektu tej klasy oceniającej podawać mu dany parametr (np enum) i potem zgodnie z tym parametrem oceniać osobniki według danej metody oceniającej ustawionej przez ten parametr.

np. w klasie OcenFitness mam 2 metody

double ocenLiniowo(osobnik o1, osobnik o2) return  o1-o2
double ocenKwadratowo(osobnik o1, osobnik o2) return (o1-o2)*(o1-o2)

tworzę obiekt (argument to jakiś enum)

OcenFitness juror = OcenFitness(LINIOWO)

i teraz przy wywoływaniu np:

juror.ocen(o1,o2)

chcę, żeby wykonywała się metoda 'ocenLiniowo'
mam 2 pomysły:

  1. na switchach\ifach
  2. tablica z funkcjami, enumy to indexy przez co nie mamy ifów i jest szybciej(?)

Moje pytanie:
Jak powinno to być zrobione, żeby było szybko, przejrzyście itp?

0

Możesz użyć std::function do przetrzymywania funkcji. std::function jest względnie drogie w użyciu, ale będzie bardzo czytelne i elastyczne. Możesz też poszukać wydajniejszych alternatyw (np. wskaźnik na funkcję), albo zrobić to co robi biblioteka standardowa i przekazać funkcję jako obiekt-parametr szablonu (za przykładem: https://dev.krzaq.cc/post/you-dont-need-a-stateful-deleter-in-your-unique_ptr-usually/ )

1

O if nawet nie myśl w tym wypadku.

Wzorzec strategia, więc masz do wyboru parę możliwości:

  • std::function
using CompareMethod = std::function<double(const osobnik&, const osobnik&)>;

class OcenFitness 
{
public:
    explicit OcenFitness(CompareMethod cmp)
         :cmp(cmp)
    {}
    void robCos(const osobnik& a, const osobnik& b)
    {
         auto waga = cmp(a, b);
         ....
    }

private:
    CompareMethod cmp;
};
  • szablon
template <class Cmp>
class OcenFitness 
{
public:

    void robCos(const osobnik& a, const osobnik& b)
    {
         auto waga = cmp(a, b);
         ....
    }

private:
    Cmp cmp;
}
  • interface
class Comparation
{
public:
    virtual ~Comparation() {}

    virtual double compare(const osobnik& a, const osobnik& b);
};

class LinearComparation : public Comparation
{
     public:
         double compare(const osobnik& a, const osobnik& b) override
         {
                return ...;
         }
};

class OcenFitness 
{
public:
     explicit OcenFitness(Comparation *cmp)
          : cmp(cmp)
     {}

    void robCos(const osobnik& a, const osobnik& b)
    {
         auto waga = cmp->compare(a, b);
         ....
    }

private:
     Comparation *cmp;
};

Każda możliwość ma swoje wady i zalety.

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