mam kilka podstawowych drzew dziedziczenia:Jak ustalić, która funkcja jest wywoływana na podstawie typu obiektów w kontenerze?
class Base {
virtual double func() = 0;
// functionality is not important for the problem
// but it's good to know that Base has some virtual functions
};
class DerivedA : public Base {
virtual double func() {}; // implementation A
};
class DerivedB : public Base {
virtual double func() {}; // implementation B
};
mam pojemnik zawierający wskaźnik albo DerivedA
lub DerivedB
przypadkach.
void f1(std::vector<Base*> a)() { /* some code */ }
int main(in, char**) {
std::vector<Base*> base_container;
f1(base_container); // works fine
}
Prawie wszystko działa na bazie, ale mam pewne funkcje, niewymienione w DerivedA
lub DerivedB
, który jest specyficzny realizacji, ale działa na DerivedA
lub DerivedB
pojemniku. Załóżmy następujący fragment kodu:
void f2(std::vector<DerivedA*> a)() { /* implementation A specific code */ }
void f2(std::vector<DerivedB*> a)() { /* implementation B specific code */ }
Jaką najlepszą praktyką jest wywoływanie prawidłowej funkcji? Wymieniłem kilka możliwych rozwiązań, które przyszły mi do głowy, ale wszystkie mają poważne wady.
Mogę przechowywać wszystkie dane w konkretnych kontenerach implementacyjnych. Jednak
f1()
nie będzie już działać, ponieważstd::vector<DerivedA*>
nie jest dzieckiemstd::vector<Base*>
(z dobrych powodów!).Mogłem ręcznie rzucać wszystkie obiekty przez cały czas, ale to jest brzydkie.
mogę ręcznie nazwać właściwą funkcję, która oczekuje pojemnik podstawowy, dając im charakterystyczną nazwę (jak
f2_a
if2_b
), ale wydaje się brzydki.Mogę zaimplementować f2 jako specjalizację szablonu funkcji, ale wydaje się to być nadużyciem.
Mogę spróbować, aby funkcja na pojemniku była zależna tylko od funkcji obiektów w kontenerze, a następnie zaimplementować dla nich funkcje przeciążone. Jest to dobre rozwiązanie w kilku przypadkach, ale w moim przypadku jest to funkcja na kontenerze, dająca różne implementacje na pojemniku dla
DerivedA
iDerivedB
, a nie tylko iterowanie zawartości kontenera.
Jak wprowadzić takie rzeczy? Jak mogę uzyskać kontener, który można przekazać zarówno do f1()
i f2()
?
Co zrobiłby "f2()" dla kontenera, który zawierał dwa obiekty, jeden "DerivedA", a drugi "DerivedB"? –
Czy możesz podać przykład, dlaczego może to być przydatne? Nie widzę tego.Z punktu widzenia OO, wydaje się, że jest brudny. To może być powód, dla którego twoje podejścia okazują się również brzydkie? –
Możesz mieć rację. Jestem w uczeniu maszynowym niché. Tak więc moja baza jest modelem predykcyjnym, podczas gdy klasy pochodne są modelami regresji lub klasyfikacji. Teraz chcę obliczyć pomiary dokładności modeli i różnią się one od klasyfikacji i regresji. – hildensia