Jeg er stødt ind i et interessant problem i forbindelse med pass-by-reference af objekter til en function, a la
func(obj &a);
Og jeg håber at I kan give mig lidt hjælp til at løse det.
I min kode angiver jeg ofte 3D koordinater som argumenter til funktioner, og for at gøre koden mere overskuelig har jeg defineret en klasse, Coord3D, som indeholder x,y og z, og har en constructor
Funktioner med koordinater som parametre, kaldes da således:
SetGeometry(Coord3D(1,2,3),Coord3D(4,5,6),...);
Hvilket går godt så længe at funktionen er call-by-value:
void SetGeometry(Coord3D a, Coord3D b, ...);
Problemet opstår hvis jeg, i et forsøg på at optimere koden, ændrer SetGeometry() til call-by-reference i stedet.
void SetGeometry(Coord3D &a, Coord3D &b, ...);
Herefter vil g++ ikke længere godtage f.eks. Coord3D(1,2,3) som argument. Jeg kan ikke gennemskue hvorfor. Problemet har dog givet mig grund til at studse over hvad der helt præcist sker når jeg f.eks. angiver Coord3D(...) som et argument. I det hele taget vil jeg gerne vide hvad compileren gør ved følgende kode:
Coord3D(1,2,3); Coord3D c(1,2,3); Coord3D d = Coord3D(1,2,3);
Som compiler uden problemer. Ryger objekterne bare på stakken, og i givet fald, hvorfor godtages Coord3D(...) så ikke?
En lidt længere forklaring: Midlertidige objekter som man opretter i forbindelse med et kald af en funktion, er som udgangspunkt const. Det er sådan set logisk nok, tallene 1, 2, 3 i dit tilfælde er const, man kan ikke modificere dem. Man kan også sige at det ikke rigtigt giver mening at forsøge at modificere midlertidige objekter, hvis man vil modificere noget, må man oprette et objekt. Disse midlertidige objekter bliver oprettet på stakken, og eksisterer kun så længe funktionskaldet varer.
Du nævner selv tre tilfælde: Coord3D(1,2,3); Her sker der (sandsynligvis) intet, der bliver ikke oprettet noget objekt.
Coord3D c(1,2,3); Her bliver objektet c oprettet på normal vis, med kald til constructoren.
Coord3D d = Coord3D(1,2,3); Umiddelbart ville man forvente at der blev oprettet et objekt på højreside, som man tog et kopi af, for at oprette d. Men i virkeligheden bliver d konstrueret på præcis samme måde som c ovenfor, så der er ingen forskelle på de to sidste eksempler.
Mange tak for svaret! At gøre parametrene const løste problemet.
Jeg forstår dog stadig ikke helt hvorfor det er nødvendigt med const. Selvom det oftest er meningsløst at ændre i et midlertidigt objekt, så burde der vel ikke være noget til hindring for at gøre det? Siden Coord3D(1,2,3) objektet jo nødvendigvis må blive lagt på stakken, hvorfor godtages det så ikke med mindre at parameteren er angivet som const?
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.