Avatar billede _NielsGM Nybegynder
13. februar 2011 - 18:05 Der er 3 kommentarer

Effekten af forskellige måder at oprette objekter

Hej eksperter!

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

Coord3D(double x, double y, double z){
this->x = x;
this->y = y;
this->z = z;
}

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?

Håber at I kan give lidt input :-)

Hilsen Niels
Avatar billede bertelbrander Novice
13. februar 2011 - 18:19 #1
Mon ikke det virker hvis du laver parametrene const?
void SetGeometry(const Coord3D &a, const Coord3D &b)
Avatar billede bertelbrander Novice
13. februar 2011 - 18:34 #2
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.
Avatar billede _NielsGM Nybegynder
13. februar 2011 - 18:59 #3
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?
Avatar billede Ny bruger Nybegynder

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.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester