Wpis z mikrobloga

  • 0
@Ulyssos: nie. Virtualizm działa tutaj dobrze jednak to jaka funkcja zostanie wywołana decydowane jest w trakcie czasu wykonywania a wartości parametrów domyślnych są ustalane w trakcie czasu kompilowania. Stąd takie niezbyt domyślne zachowanie
@Ulyssos: ponieważ A::func() jest wirtualna, definicja jej ciała zostaje nadpisana w klasie dziedziczącej, jednak wywołując tą metodę używając wskaźnika typu A* na B korzystasz z sygnatury metody zdefiniowanej dla A::func() gdzie jest właśnie zdefiniowany domyślny parametr 1

Jeżeli wywołałbyś func używając takiego potworka
((B*)ptr)->func();
To dostaniesz
2 from B
@Ulyssos: parametry domyślne są rozwiązywane statycznie po stronie callera, PRZED wywołaniem, na podstawie typu znanego w czasie kompilacji, dlatego 1. Funkcja z parametrem domyślnym jest kompilowana tak samo jak każda inna funkcja - ma parametr, który musi być skądś dostarczony.

W języku Scala rozwiązano ten problem lepiej - wartości domyślne nie są wstawiane statycznie przez kompilator, a kompilator generuje wywołanie dodatkowej metody wirtualnej w celu obliczenia wartości domyślnej (co oczywiście wiąże
W języku Scala rozwiązano ten problem lepiej - ... (co oczywiście wiąże się z narzutem ale przynajmniej zachowuje się przyzwoicie).


@Krolik: "lepiej" to pojęcie względne. Rozważ przypadek w ktorym stworzysz obiekt typu A, wtedy wszystko zaczyna mieć sens.

Jakiej innej wartości domyślnej byś się spodziewał używając wskaźnika na A?
@MilionoweMultikonto: przecież w Scali będzie działać dobrze. Jak stworzysz obiekt typu A to wstawi wartość domyślną dla A. Jak stworzysz obiekt B to niezależnie od typu wskaźnika (A czy B) użyje wartości domyślnej z B. Większość ludzi spodziewa się że to tak będzie działać i tak właśnie działa. W C++ jest nieintuicyjne - bo wartości domyślne zachowują się statycznie na podstawie typu czasu kompilacji a implementacja już działa dynamicznie na podstawie