Mam to pytanie, gdy otrzymałem komentarz z komentarzem do kodu, mówiąc, że funkcje wirtualne nie muszą być wstawiane.Czy wbudowane funkcje wirtualne są naprawdę pozbawione sensu?
Pomyślałem, że wbudowane funkcje wirtualne mogą się przydać w scenariuszach, w których funkcje są wywoływane bezpośrednio na obiektach. Ale moim przeciw-argumentem stało się - dlaczego chciałoby się zdefiniować wirtualne, a następnie użyć obiektów do wywoływania metod?
Najlepiej nie używać wbudowanych funkcji wirtualnych, ponieważ i tak prawie nigdy nie są one rozwijane?
Fragment kodu użyłem do analizy:
class Temp
{
public:
virtual ~Temp()
{
}
virtual void myVirtualFunction() const
{
cout<<"Temp::myVirtualFunction"<<endl;
}
};
class TempDerived : public Temp
{
public:
void myVirtualFunction() const
{
cout<<"TempDerived::myVirtualFunction"<<endl;
}
};
int main(void)
{
TempDerived aDerivedObj;
//Compiler thinks it's safe to expand the virtual functions
aDerivedObj.myVirtualFunction();
//type of object Temp points to is always known;
//does compiler still expand virtual functions?
//I doubt compiler would be this much intelligent!
Temp* pTemp = &aDerivedObj;
pTemp->myVirtualFunction();
return 0;
}
Rozważmy kompilacji przykład z niezależnie od potrzebnych przełączników, aby uzyskać listę asemblerów, a następnie pokazując przeglądarkę kodu, która rzeczywiście może kompilować wbudowane funkcje wirtualne. –
Powyższe z reguły nie będzie inline, ponieważ wywołujesz funkcję wirtualną na poziomie klasy bazowej. Chociaż zależy to tylko od tego, jak inteligentny jest kompilator. Gdyby można było wskazać, że 'pTemp-> myVirtualFunction()' może być rozpoznany jako połączenie inne niż wirtualne, może zainicjować to połączenie. To wywołanie referencyjne jest wstawiane za pomocą g ++ 3.4.2: 'TempDerived & pTemp = aDerivedObj; pTemp.myVirtualFunction(); 'Twój kod nie jest. – doc
Jedną z rzeczy, którą faktycznie robi gcc, jest porównanie wejścia vtable z konkretnym symbolem, a następnie użycie wstawionego wariantu w pętli, jeśli pasuje. Jest to szczególnie użyteczne, jeśli funkcja inlined jest pusta, a pętlę można w tym przypadku wyeliminować. –