Tak więc, opierając się na pobieżnym wyszukiwaniu, już wiem, że wywołanie funkcji wirtualnej (czystej lub innej) z konstruktora nie jest możliwe. Przebudowałem swój kod, aby upewnić się, że tego nie robię. Chociaż to powoduje, że użytkownik moich klas może dodać dodatkowe wywołanie funkcji w swoim kodzie, to naprawdę nie jest to wielka sprawa. Mianowicie, zamiast wywoływać konstruktora w pętli, nazywają teraz funkcję, która (w rzeczywistości!) Zwiększa wydajność kodu, ponieważ nie mamy za zadanie budowania i niszczenia danego obiektu za każdym razem.Wywołanie funkcji czystej wirtualnej z funkcji członka abstrakcyjnej bazy klasy?
Mam jednak natknął się coś ciekawego ...
w abstrakcyjnej klasie mam coś takiego:
// in AbstractClass.h:
class AbstractClass {
public:
AbstractClass() {}
virtual int Func(); //user can override
protected:
// Func broken up, derived class must define these
virtual int Step1() = 0;
virtual int Step2() = 0;
virtual int Step3() = 0;
// in AbstractClass.cpp:
int AbstractClass::Func() {
Step1();
// Error checking goes here
Step2();
// More error checking...
// etc...
}
Zasadniczo istnieje wspólna struktura, która czyści funkcje wirtualne śledzić najbardziej czasu, ale jeśli nie, funkcja Func() jest wirtualna i umożliwia klasie pochodnej określenie kolejności. Jednak każdy krok musi być zaimplementowany w klasach pochodnych.
Po prostu chciałem mieć pewność, że nie ma niczego, co koniecznie robię źle tutaj, ponieważ funkcja Func() nazywa czyste wirtualne. Oznacza to, że przy użyciu klasy bazowej, jeśli wywołasz StepX(), złe rzeczy się zdarzą. Jednak klasa jest wykorzystywana przez tworzenie obiektu pochodnego, a następnie wywoływanie Func() (np. MyDerivedObject.Func();) na tym obiekcie pochodnym, który powinien mieć wszystkie czyste funkcje wirtualne przeciążone poprawnie.
Czy jest coś, czego mi brakuje lub robię nieprawidłowo, postępując zgodnie z tą metodą? Dzięki za pomoc!
To jest podręcznikowy przykład używania idiomu [Non-Virtual Interface idiom] (http://en.wikipedia.org/wiki/Non-virtual_interface_pattern) do implementacji [Wzorca metody szablonów] (http: // en. wikipedia.org/wiki/Template_pattern). – Casey
Aby wyjaśnić, istnieje duża różnica między "wywoływaniem funkcji wirtualnych w konstruktorze" i "wywoływaniem funkcji czysto wirtualnych". Ten pierwszy jest podchwytliwy i zniechęcony (choć ważny), drugi jest całkowicie błędny (a także nie całkiem trywialny). –
Wywołanie funkcji wirtualnej w konstruktorze lub destruktorze nie jest "nie do przyjęcia", chyba że nie zawracasz sobie głowy zrozumieniem, jak działają. –