334b4ec3cead8220be7fec50e4d7396b
Jeg er ved at lære C++, og jeg er lige begyndt at gå ind i virtuelle funktioner.


Efter hvad jeg har læst (i bogen og på nettet) er virtuelle funktioner funktioner i basisklassen, som man kan overskrive i afledte klasser.


Men tidligere i bogen, da jeg lærte om grundlæggende arv, var jeg i stand til at overskrive basisfunktioner i afledte klasser uden at bruge `virtual`.


Så hvad er det, jeg går glip af her? Jeg ved, at der er mere om virtuelle funktioner, og det ser ud til at være vigtigt, så jeg vil gerne være klar over, hvad det præcist er. Jeg kan bare ikke finde et klart svar online.


Hvorfor har vi brug for virtuelle funktioner i C++?
===================================================


answer-id.com
2021.43
Du har brug for mindst 1 arveligt niveau og en nedkastning for at demonstrere det. Her er et meget simpelt eksempel:



```
class Animal
{        
    public: 
      // turn the following virtual modifier on/off to see what happens
      //virtual   
      std::string Says() { return "?"; }  
};

class Dog: public Animal
{
    public: std::string Says() { return "Woof"; }
};

void test()
{
    Dog* d = new Dog();
    Animal* a = d;       // refer to Dog instance with Animal pointer

    cout << d->Says();   // always Woof
    cout << a->Says();   // Woof or ?, depends on virtual
}
```

Hvis basisklassen er `Base` og en afledt klasse er `Der`, kan du have en `Base *p`-pointer, som faktisk peger på en instans af `Der`. Når du kalder `p->foo();`, hvis `foo` er **ikke** virtuel, så udføres `Base`'s version af den, og der ignoreres det faktum, at `p` faktisk peger på en `Der`. Hvis foo **er** virtuel, udfører `p->foo()` "leafmost" override af `foo`, idet der fuldt ud tages hensyn til den faktiske klasse af det element, der peges på. Så forskellen mellem virtuel og ikke-virtuel er faktisk ret afgørende: førstnævnte muliggør runtime [polymorphism](https://en.wikipedia.org/wiki/Type_polymorphism), som er kernebegrebet i OO-programmering, mens sidstnævnte ikke gør det.


Du skal skelne mellem overriding og overloading. Uden nøgleordet `virtual` kan du kun overloade en metode i en basisklasse. Det betyder ikke andet end at gemme sig.
Lad os sige, at du har en basisklasse `Base` og en afledt klasse `Specialized`, som begge implementerer `void foo()`. Nu har du en pointer til `Base`, der peger på en instans af `Specialized`. Når du kalder `foo()` på den, kan du observere den forskel, som `virtual` gør: Hvis metoden er virtuel, vil implementeringen af `Specialized` blive brugt, hvis den mangler, vil versionen fra `Base` blive valgt.
Det er den bedste praksis aldrig at overloade metoder fra en basisklasse. At gøre en metode ikke-virtuel er forfatterens måde at fortælle dig, at det ikke er hensigten at udvide den i underklasser.

