Nada

2D1387, Programsystemkonstruktion med C++, 4 poäng

FAQ -- vanliga frågor på laborationerna:

1 Virtuella funktioner

2 Mallar 3 Kompileringfel och länkfel

1 Virtella funktioner

1.1 Varför fungerar inte virtuella funktioner i konstruktorn/destruktorn?

Detta är en följd av att objektet inte är färdigskapat i konstruktorn. De anrop i konstruktorn A::A() som använder funktioner som är deklarerade virtual kommer att köra funktioner i klassen A eller dess basklasser och inte i A:s nedärvda klasser som man kunde förvänta sig. Om du måste köra en viss funktion i konstruktorn måste den alltså ligga i klassen själv (eller dess basklasser). På samma sätt fungerar det för destruktorer eftersom objektet där kan vara delvis förstört.

1.2 Varför måste en strikt virtuell destruktor ha en definition?

Destruktorerna körs automatiskt när objektet förstörs: först i nedärvda klasser och sedan uppåt i hierarkin tills dess att destruktorn för basklassen körs. Trots att basklassen är abstrakt körs alltså destruktorn och därför måste den ha en definition.

2 Mallar

2.1 Malldefinitioner måste ligga i headerfilen.

Dagens kompilatorer kompilerar filerna separat till objektfiler och använder sedan länkaren för att sätta ihop objektfilerna till ett körbart program. Länkaren kan inte använda objektfilerna för att skapa de malldefinitioner du behöver. Detta innebär att länkaren inte kommer att hitta de mallfunktioner eller funktioner i mallklasser du försöker köra. En lösning på problemet är att lägga allt som har med mallarna i headerfilen så att de syns vid kompileringstillfället.

2.2 Kompilatorn (länkaren) kan inte hitta mina mallfunktioner.

Svaret på varför du får felmeddelanden finns i fråga
2.1.

2.3 Varför klagar kompilatorn på konstruktorn i min mallklass då klassen ligger i en namnrymd?

Det verkar som om g++ (obefogat) klagar då man ger definitionen av klassen utanför namnrymden. En lösning är att omge definitionen av klassen med namespace{ ... } så kompilerar koden. Se
exempelfil för exempel på lösning på problemet.

2.4 Hur anger jag en friend operator<< i en mallklass?

När man ska skapa en friendfunktion måste man skriva frienddeklarationen precis som i deklarationen utanför klassen. Eftersom operator<<() tar ett argument som är en mallklass kommer dess deklaration börja med template<S>. Följdaktligen måste även frienddeklarationen börjas med template<S> för att matcha. Se
exempelfil för exempel.

3 Kompileringfel och länkfel

3.1 Länkfel: unresolved symbol: <basklass> type_info node/function.

Detta länkfel uppstår då man glömmer att ge definiera en funktion som inte är strikt virtuell i sin abstrakta basklass. För att lösa problemet kan man lägga till tomma kroppar på alla funktioner (som inte är strikt virtuella) som saknar kropp.

3.2 Länkfel: Länkaren kan inte hitta konstruktorn/destruktorn till min basklass.

Samma orsak och lösningsförslag som
3.1.

3.3 Länkfel: unresolved symbol: <klass> virtual table.

En möjlig orsak till detta fel är att man glömt definiera kroppen till någon virtuell funktion. Det är länkarens uppgift att se till att alla funktioner går att hitta och om inte, ge ett felmeddelande. Alltså: se till att samtliga funktioner har en implementation, och att implementationen finns med i någon av de filer som länkas in. Felmeddelandet betyder att den virtuella tabellen, som håller adresserna till de virtuella funktionerna, inte är komplett.

^ Upp till kursens hemsida.


Sidansvarig: Johnny Bigert
Senast ändrad 11 december 2000
Tekniskt stöd: <webmaster@nada.kth.se>