Vad är virtuell arv?
Virtuell arv är en typ av arv där implementeringen av en superklass är ofullständig och en underklass krävs för fullständig definition av ett objekt. Denna typ av arv kan användas i samband med både enkel och multipel arv, men används oftast vid multipel arv. Varje klass som ärver från en virtuell basklass blir en direkt underklass för den basklassen. En virtuell basklass kan lita på en underklass för att implementera alla dess metoder, men detta är inte ett krav.
C ++ är det mest kända datorspråket för att använda virtuella arv. För att förklara virtuell arv i C ++ används det "virtuella" nyckelordet. Både superklassen och underklassen måste förklara virtuella metoder med det "virtuella" nyckelordet. Detta säger C ++ -kompileraren att superklassen är ofullständig, och den måste få information från underklassen för att slutföra den. Att använda underklassen för att slutföra superklassen betyder inte att underklasser skriver över varandra om de har samma basklass, och istället tar C ++-kompilatorn hand om att bestämma vilka delar som går med varje objekt.
Eftersom en virtuell basklass krävs för virtuell arv kan globala funktioner i C ++ inte förklaras virtuella. Denna arvtyp kan endast användas när man följer objektorienterade programmeringsprinciper (OOP). Anledningen till detta är att globala funktioner inte är associerade med en viss klass, och därför vanligtvis är fristående på egen hand. Utan en superklass och underklass kan arv inte ske, så globala funktioner och virtuella arv är ömsesidigt exklusiva. Globala funktioner kan i teorin användas i virtuella funktioner, men det omvända kanske inte alltid fungerar.
Virtuell arv används för att lösa många programmeringsproblem, och en av de mest användbara är lösningen av tvetydighet. Vid flera arv kan man ha en basklass A som har två underklasser, B och C, och sedan en klass D som ärver från båda klasserna B och C. Detta mönster kallas vanligtvis "dödsdiamanten" eftersom om klasserna A, B och C har alla implementationer av samma metod, det är inte möjligt för klass D att avgöra vilken implementering den ska använda. Virtuell arv löser detta problem eftersom varje klassens implementering förblir distinkt och därför otvetydig. Denna distinktion hanteras av specialiserade interna objekt som kallas virtuella tabeller (vtables) som håller reda på varje objekttyp, men dessa tabeller behöver inte exakt manipuleras av en programmerare eftersom de är inbyggda i språket.