Czytam Effective C++, a tam jest "Element 9: Nigdy nie wywołuj funkcji wirtualnych podczas budowy lub zniszczenia". I zastanawiam się, czy mój kod jest w porządku, nawet jeśli złamie tę zasadę:Wywołanie funkcji wirtualnej od konstruktora
using namespace std;
class A{
public:
A(bool doLog){
if(doLog)
log();
}
virtual void log(){
cout << "logging A\n";
}
};
class B: public A{
public:
B(bool doLog) : A(false){
if(doLog)
log();
}
virtual void log(){
cout << "logging B\n";
}
};
int main() {
A a(true);
B b(true);
}
Czy jest coś nie tak z tym podejściem? Czy mogę wpaść w kłopoty, gdy zrobię coś bardziej skomplikowanego?
To szokuje, że większość odpowiedzi nie dostała tego, co tam zrobiłem, i po prostu wyjaśniła ponownie, dlaczego wywołuje funkcję wirtualną od konstruktora potencjalnie niebezpiecznego.
Chciałbym podkreślić, że wyjście z mojego programu wygląda następująco:
logging A
logging B
Więc dostać zalogowany, gdy jest on skonstruowany i B zalogowany, gdy jest on zbudowany. I to właśnie chcę chce! Ale pytam, czy znajdziesz coś złego (potencjalnie niebezpiecznego) z moim "hack", aby przezwyciężyć problem wywoływania funkcji wirtualnej w konstruktorze.
W tym przypadku załatałeś to dobrze, ale jeśli inne osoby będą musiały użyć tego kodu, błędy będą musiały się zdarzyć. –
@JoachimPileborg to nie jest prawda: zachowanie * jest * zdefiniowane. Podczas budowy wirtualne wywołania funkcji są wyłączone (np. Używana jest implementacja obecnie konstruującego typu). –