Thread View: be.comp.programming
17 messages
17 total messages
Started by Johan Vervloet
Wed, 28 May 2003 11:49
[C++] function overloading en typedef
Author: Johan Vervloet
Date: Wed, 28 May 2003 11:49
Date: Wed, 28 May 2003 11:49
33 lines
1730 bytes
1730 bytes
Hallo,
Ik zit met een probleem gelijkaardig aan het volgende :
Stel ik heb een klasse GekleurdeInt, en ik wil die als volgt definieren :
typedef int Kleur; // proper niwaar :-)
class GekleurdeInt
{
public:
GekleurdeInt( int i );
GekleurdeInt( Kleur k );
/* enz */
};
Dit werkt dus niet, aangezien int en Kleur voor de compiler van hetzelfde
datatype zijn.
Bestaat er hiervoor een mooie oplossing, zonder hiervoor een hele nieuwe
klasse Kleur te moeten maken ?
Bedankt,
Johan
--
/"\ ASCII Ribbon Campaign
\ / against HTML email and proprietary formats
X
/ \ http://www.gewestpallieter.be/~johan/asciirib.php
Re: [C++] function overloading en typedef
Author: Roel Schroeven
Date: Wed, 28 May 2003 11:58
Date: Wed, 28 May 2003 11:58
29 lines
1915 bytes
1915 bytes
Johan Vervloet wrote:
> Hallo,
>
> Ik zit met een probleem gelijkaardig aan het volgende :
>
> Stel ik heb een klasse GekleurdeInt, en ik wil die als volgt definieren :
>
> typedef int Kleur; // proper niwaar :-)
>
> class GekleurdeInt
> {
> public:
> GekleurdeInt( int i );
> GekleurdeInt( Kleur k );
> /* enz */
> };
>
> Dit werkt dus niet, aangezien int en Kleur voor de compiler van hetzelfde
> datatype zijn.
>
> Bestaat er hiervoor een mooie oplossing, zonder hiervoor een hele nieuwe
> klasse Kleur te moeten maken ?
Gewoon de eerste constructor weglaten?
--
"Codito ergo sum"
Roel Schroeven
Re: [C++] function overloading en typedef
Author: Johan Vervloet
Date: Wed, 28 May 2003 12:26
Date: Wed, 28 May 2003 12:26
18 lines
1507 bytes
1507 bytes
Roel Schroeven wrote: > > Gewoon de eerste constructor weglaten? In dit geval lost dat veel op natuurlijk, maar in de echte versie van mijn probleem heb ik zowel de constructor met een int als argument als de constructor met de typedef nodig. Johan > -- /"\ ASCII Ribbon Campaign \ / against HTML email and proprietary formats X / \ http://www.gewestpallieter.be/~johan/asciirib.php
Re: [C++] function overloading en typedef
Author: Dominique Devriese
Date: Wed, 28 May 2003 12:59
Date: Wed, 28 May 2003 12:59
45 lines
2449 bytes
2449 bytes
Johan Vervloet writes:
Johan> Hallo, Ik zit met een probleem gelijkaardig aan het volgende
Johan> :
Johan> Stel ik heb een klasse GekleurdeInt, en ik wil die als volgt
Johan> definieren :
Johan> typedef int Kleur; // proper niwaar :-)
Johan> class GekleurdeInt { public:
Johan> GekleurdeInt( int i ); GekleurdeInt( Kleur k
Johan> );
Johan> /* enz */ };
Johan> Dit werkt dus niet, aangezien int en Kleur voor de compiler
Johan> van hetzelfde datatype zijn.
Johan> Bestaat er hiervoor een mooie oplossing, zonder hiervoor een
Johan> hele nieuwe klasse Kleur te moeten maken ?
het zgn. "Named Constructor Idiom" [1] kan hier mss helpen ?
Kort samengevat wordt dat dus:
typedef int Kleur;
class GekleurdeInt
{
public:
GekleurdeInt( int i, Kleur k );
static GekleurdeInt fromInt( int i );
static GekleurdeInt fromKleur( Kleur k );
};
sjuus
domi
Footnotes:
[1] http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.8
--
For he is the lambda and xdelta, and every opening parenthesis will be
closed at the end of all input.
(David Kastrup on alt.religion.emacs)
Re: [C++] function overloading en typedef
Author: Roel Schroeven
Date: Wed, 28 May 2003 13:13
Date: Wed, 28 May 2003 13:13
59 lines
3038 bytes
3038 bytes
Dominique Devriese wrote:
> Johan Vervloet writes:
>
> Johan> Hallo, Ik zit met een probleem gelijkaardig aan het volgende
> Johan> :
>
> Johan> Stel ik heb een klasse GekleurdeInt, en ik wil die als volgt
> Johan> definieren :
>
> Johan> typedef int Kleur; // proper niwaar :-)
>
> Johan> class GekleurdeInt { public:
> Johan> GekleurdeInt( int i ); GekleurdeInt( Kleur k
> Johan> );
> Johan> /* enz */ };
>
> Johan> Dit werkt dus niet, aangezien int en Kleur voor de compiler
> Johan> van hetzelfde datatype zijn.
>
> Johan> Bestaat er hiervoor een mooie oplossing, zonder hiervoor een
> Johan> hele nieuwe klasse Kleur te moeten maken ?
>
> het zgn. "Named Constructor Idiom" [1] kan hier mss helpen ?
>
> Kort samengevat wordt dat dus:
>
> typedef int Kleur;
>
> class GekleurdeInt
> {
> public:
> GekleurdeInt( int i, Kleur k );
> static GekleurdeInt fromInt( int i );
> static GekleurdeInt fromKleur( Kleur k );
> };
GekleurdeInt foo = GekleurdeInt::fromInt(123);
Dat wil dan wel zeggen dat je bij elke initialisatie eerst een object
gaat aanmaken, en het dan kopi�ren. Voor kleine klassen niet erg, voor
grotere zaken is dat wel lastig.
Als je de objecten met new maakt is het geen probleem:
typedef int Kleur;
class GekleurdeInt
{
public:
GekleurdeInt( int i, Kleur k );
static GekleurdeInt* fromInt( int i );
static GekleurdeInt* fromKleur( Kleur k );
};
GekleurdeInt *foo = GekleurdeInt::fromInt(123);
--
"Codito ergo sum"
Roel Schroeven
Re: [C++] function overloading en typedef
Author: Dominique Devriese
Date: Wed, 28 May 2003 13:30
Date: Wed, 28 May 2003 13:30
27 lines
2493 bytes
2493 bytes
Roel Schroeven writes: Johan> GekleurdeInt( int i ); GekleurdeInt( Kleur k ); /* enz */ }; Johan> Dit werkt dus niet, aangezien int en Kleur voor de compiler Johan> van hetzelfde datatype zijn. >> het zgn. "Named Constructor Idiom" [1] kan hier mss helpen ? Roel> GekleurdeInt foo = GekleurdeInt::fromInt(123); Roel> Dat wil dan wel zeggen dat je bij elke initialisatie eerst een Roel> object gaat aanmaken, en het dan kopi�ren. Voor kleine klassen Roel> niet erg, voor grotere zaken is dat wel lastig. Je kan die static methodes inline maken, als je echt denkt dat dat een probleem is. Maar ik denk niet dat het kopieren van twee integers erg grote problemen gaat opleveren, tenzij je het enorm veel keer doet, en dan heb je andere problemen.. sjuus domi -- One cannot escape the feeling that these mathematical formulas have an independent existence and an intelligence of their own, that they are wiser htan we are, wiser even than their discoverers, that we get more out of them than we put into them. ( Heinrich Hertz on Maxwell's equations for electromagnetism )
Re: [C++] function overloading en typedef
Author: Roel Schroeven
Date: Wed, 28 May 2003 13:32
Date: Wed, 28 May 2003 13:32
34 lines
2705 bytes
2705 bytes
Dominique Devriese wrote: > Roel Schroeven writes: > > Johan> GekleurdeInt( int i ); GekleurdeInt( Kleur k ); /* enz */ }; > Johan> Dit werkt dus niet, aangezien int en Kleur voor de compiler > > Johan> van hetzelfde datatype zijn. > >> het zgn. "Named Constructor Idiom" [1] kan hier mss helpen ? > > Roel> GekleurdeInt foo = GekleurdeInt::fromInt(123); > > Roel> Dat wil dan wel zeggen dat je bij elke initialisatie eerst een > Roel> object gaat aanmaken, en het dan kopi�ren. Voor kleine klassen > Roel> niet erg, voor grotere zaken is dat wel lastig. > > Je kan die static methodes inline maken, als je echt denkt dat dat een > probleem is. Dat helpt niet he: GekleurdeInt::fromInt(123) geeft een object als resultaat, inline of niet, en door foo = ... wordt heel dat object gekopieerd. > Maar ik denk niet dat het kopieren van twee integers erg > grote problemen gaat opleveren, tenzij je het enorm veel keer doet, en > dan heb je andere problemen.. Dat is juist, als die klasse niet meer data bevat dan die twee ints zal het geen probleem zijn. Een oplossing die meer scalable is zou nog mooier zijn :) -- "Codito ergo sum" Roel Schroeven
Re: [C++] function overloading en typedef
Author: Bert Peers
Date: Wed, 28 May 2003 13:59
Date: Wed, 28 May 2003 13:59
31 lines
2238 bytes
2238 bytes
Johan Vervloet wrote:
> typedef int Kleur; // proper niwaar :-)
Nee, niet proper ;) En wel hierom :
Een typedef is eigenlijk maar een veredelde macro. Een hack
uit die goeie ouwe C tijd, om het toch nog een _beetje_
verstaanbaar te houden. ;)
Wat je eigenlijk zegt is : omdat je het niet ziet zitten om
van Kleur een klasse te maken, ga je al de kennis die nodig is
om het onderscheid te maken tussen Kleur en int (kennis die
normaal in die klasse zou zitten), gaan rondstrooien bij de
gebruikers van Kleur (zoals GekleurdeInt), maw je plaatst
de verantwoordelijkheid om het verschil te kennen tussen
Kleur en int bij de gebruikers van het concept, ipv in het
concept zelf. Ik zou zeggen, ga d'rvoor en maak er gewoon
een struct van. 1 constructor en 1 operator int () en je
bent er van af ;)
> class GekleurdeInt
> {
> public:
> GekleurdeInt( int i );
> GekleurdeInt( Kleur k );
> /* enz */
> };
Bert
Re: [C++] function overloading en typedef
Author: Dominique Devriese
Date: Wed, 28 May 2003 16:22
Date: Wed, 28 May 2003 16:22
36 lines
2677 bytes
2677 bytes
Roel Schroeven writes: Roel> Dominique Devriese wrote: >> Roel Schroeven writes: Johan> GekleurdeInt( int i ); GekleurdeInt( Kleur k ); /* enz */ }; Johan> Dit werkt dus niet, aangezien int en Kleur voor de compiler Johan> van hetzelfde datatype zijn. >> het zgn. "Named >> Constructor Idiom" [1] kan hier mss helpen ? Roel> GekleurdeInt foo = GekleurdeInt::fromInt(123); Roel> Dat wil dan wel zeggen dat je bij elke initialisatie eerst >> een Roel> object gaat aanmaken, en het dan kopi�ren. Voor kleine klassen Roel> niet erg, voor grotere zaken is dat wel lastig. >> Je kan die static methodes inline maken, als je echt denkt dat >> dat een >> probleem is. Roel> Dat helpt niet he: GekleurdeInt::fromInt(123) geeft een object Roel> als resultaat, inline of niet, en door foo = ... wordt heel Roel> dat object gekopieerd. Hmm.. Ik kan me vergissen, maar dit is toch een heel duidelijk voorbeeld van een situatie waar een compiler de zgn. "return value optimisation" kan en mag toepassen ? sjuus domi -- VI is historically important, if "religiously evil;" (Christopher Browne on alt.religion.emacs)
Re: [C++] function overloading en typedef
Author: Nicolas Barbier
Date: Wed, 28 May 2003 18:51
Date: Wed, 28 May 2003 18:51
75 lines
3104 bytes
3104 bytes
Roel Schroeven wrote:
> Dominique Devriese wrote:
>
>> Roel Schroeven writes:
>>
>> Roel> GekleurdeInt foo = GekleurdeInt::fromInt(123);
>>
>> Roel> Dat wil dan wel zeggen dat je bij elke initialisatie eerst een
>> Roel> object gaat aanmaken, en het dan kopi�ren. Voor kleine klassen
>> Roel> niet erg, voor grotere zaken is dat wel lastig.
>>
>> Je kan die static methodes inline maken, als je echt denkt dat dat een
>> probleem is.
>
> Dat helpt niet he: GekleurdeInt::fromInt(123) geeft een object als
> resultaat, inline of niet, en door foo = ... wordt heel dat object
> gekopieerd.
/* test.cpp */
class Blaat {
public:
Blaat(int i) {
this->i = i;
}
static Blaat gimme() {
return Blaat(5);
}
private:
int i;
};
extern void bliep(const Blaat &b);
int main()
{
bliep(Blaat(1));
}
/* deel van test.s, gecompileerd met gcc 3.2, -O3, op een x86 ding */
.globl main
.type main,@function
main:
/* functie proloog */
.LFB1:
pushl %ebp
.LCFI0:
movl %esp, %ebp
.LCFI1:
subl $8, %esp
.LCFI2:
/* maak argumenten voor call naar bliep klaar */
andl $-16, %esp
subl $12, %esp
leal -4(%ebp), %edx
pushl %edx
movl $1, -4(%ebp)
.LCFI3:
/* doe call */
call _Z5bliepRK5Blaat
xorl %eax, %eax
leave
ret
Hoewel ik had verwacht dat het eerste deel van de functie beter
"samengeplakt" zou geworden zijn (de proloog wordt misschien nooit
geoptimaliseerd ofzo?), zie je duidelijk dat het object nooit gekopieerd
wordt.
Nog iets dat ik eigenaardig vind: met -fomit-frame-pointer blijft de
functie perfect hetzelfde, zou je dan niet verwachten dat die %ebp rommel
weggegooid zou worden?
--
Nicolas Barbier
Re: [C++] function overloading en typedef
Author: Bert Peers
Date: Wed, 28 May 2003 20:30
Date: Wed, 28 May 2003 20:30
37 lines
2865 bytes
2865 bytes
Nicolas Barbier wrote:
>
> static Blaat gimme() {
> return Blaat(5);
>
> extern void bliep(const Blaat &b);
> int main()
> {
> bliep(Blaat(1));
>
> Hoewel ik had verwacht dat het eerste deel van de functie beter
> "samengeplakt" zou geworden zijn (de proloog wordt misschien nooit
> geoptimaliseerd ofzo?), zie je duidelijk dat het object nooit gekopieerd
> wordt.
Euh, ik kan niet goed volgen vrees ik. Was het niet je bedoeling
om iets te schrijven als bliep(Blaat::gimme()) ? Maar dan nog
weet ik niet of dit helpt -- de copy constructor wordt aangeroepen
op het moment dat de return value van de functie in de "recipient"
terecht komt. Als die recipient enkel een const& nodig heeft,
moet er niks gekopieerd worden. Ik zou zelfs bijna zeker zeggen,
"..._mag_ er niks gekopieerd worden".
Nu, het klopt wel natuurlijk dat als de compiler kan verifieren
dat die copy constructor geen neveneffecten heeft (bv omdat ie
'm zelf heeft gegenereerd), hij die mag overslaan en de functie
meteen in de recipient mag laten constructen.
> Nog iets dat ik eigenaardig vind: met -fomit-frame-pointer blijft de
> functie perfect hetzelfde, zou je dan niet verwachten dat die %ebp rommel
> weggegooid zou worden?
Misschien enkel als er echt een tekort aan registers ontstaat ?
De disassembly blijft toch nog net iets verstaanbaarder met ebp,
vandaar misschien.. kweetniet :)
Bert
Re: [C++] function overloading en typedef
Author: Nicolas Barbier
Date: Wed, 28 May 2003 21:09
Date: Wed, 28 May 2003 21:09
93 lines
3930 bytes
3930 bytes
Bert Peers wrote:
> Nicolas Barbier wrote:
> >
>> static Blaat gimme() {
>> return Blaat(5);
>>
>> extern void bliep(const Blaat &b);
>> int main()
>> {
>> bliep(Blaat(1));
>>
>> Hoewel ik had verwacht dat het eerste deel van de functie beter
>> "samengeplakt" zou geworden zijn (de proloog wordt misschien nooit
>> geoptimaliseerd ofzo?), zie je duidelijk dat het object nooit gekopieerd
>> wordt.
>
> Euh, ik kan niet goed volgen vrees ik. Was het niet je bedoeling
> om iets te schrijven als bliep(Blaat::gimme()) ?
/me slaps himself *dough* "stupid!"
Inderdaad, ik lijk even verward te zijn geweest ;-)
Hier volgt de correcte versie, die echter eveneens aantoont dat GCC dit kan
wegoptimalizeren:
/* test.cpp */
class Blaat {
public:
Blaat(int i) {
this->i = i;
}
static Blaat gimme() {
return Blaat(5);
}
private:
int i;
};
extern void bliep(const Blaat &b);
int main()
{
bliep(Blaat::gimme());
/* Hier vergeet ik iets te returnen, merk dat GCC daar zelfs met
-Wall, -ansi en -pedantic niets op zegt, en dat er in de
gegenereerde code zelfs voor gezorgd wordt dat er 0 wordt
gereturnd? */
}
/* gedeelte van test.s */
.globl main
.type main,@function
main:
.LFB1:
pushl %ebp
.LCFI0:
movl %esp, %ebp
.LCFI1:
subl $8, %esp
.LCFI2:
andl $-16, %esp
subl $12, %esp
leal -4(%ebp), %edx
pushl %edx
movl $5, -4(%ebp)
.LCFI3:
call _Z5bliepRK5Blaat
xorl %eax, %eax
leave
ret
> Maar dan nog weet ik niet of dit helpt -- de copy constructor wordt
> aangeroepen op het moment dat de return value van de functie in de
> "recipient" terecht komt.Als die recipient enkel een const& nodig heeft,
> moet er niks gekopieerd worden. Ik zou zelfs bijna zeker zeggen,
> "..._mag_ er niks gekopieerd worden".
Ben je daar zeker van? Je bedoelt dus dan in dit geval de copy-constructur
niet opgeroepen mag worden? Ik dacht altijd (puttende uit mijn absoluut
onbenullige C++ kennis :-) dat hij altijd wordt aangeroepen als je een
volledig object returnt uit een functie. Trouwens, waar zouden, bij een
gemiddelde compiler, anders de bytes van het object blijven staan? De stack
gaat meteen weer worden overschreven terwijl er via de referentie nog naar
het object kan gerefereerd worden.
Die "bliep" functie had ik er eigenlijk alleen maar bijgezet om te
voorkomen dat alles volledig zou worden weg-geoptimalizeerd :-) (niet
getest of dat ook werkelijk zo zou zijn anders).
--
Nicolas Barbier
Re: [C++] function overloading en typedef
Author: Bert Peers
Date: Wed, 28 May 2003 22:14
Date: Wed, 28 May 2003 22:14
52 lines
3684 bytes
3684 bytes
Nicolas Barbier wrote:
> int main()
> {
> bliep(Blaat::gimme());
> /* Hier vergeet ik iets te returnen, merk dat GCC daar zelfs met
> -Wall, -ansi en -pedantic niets op zegt, en dat er in de
> gegenereerde code zelfs voor gezorgd wordt dat er 0 wordt
> gereturnd? */
Dat is volgens de standaard. Als je zonder return
statement uit een functie dondert die een int zou moeten
returnen, heb je undefined behavior, _behalve_ voor
main -- daar return je vanzelf 0 (zie 3.6.1.5).
>>Maar dan nog weet ik niet of dit helpt -- de copy constructor wordt
>>aangeroepen op het moment dat de return value van de functie in de
>>"recipient" terecht komt.Als die recipient enkel een const& nodig heeft,
>>moet er niks gekopieerd worden. Ik zou zelfs bijna zeker zeggen,
>>"..._mag_ er niks gekopieerd worden".
>
> Ben je daar zeker van? Je bedoelt dus dan in dit geval de copy-constructur
> niet opgeroepen mag worden? Ik dacht altijd (puttende uit mijn absoluut
> onbenullige C++ kennis :-) dat hij altijd wordt aangeroepen als je een
> volledig object returnt uit een functie. Trouwens, waar zouden, bij een
> gemiddelde compiler, anders de bytes van het object blijven staan?
Wel, de compiler is nu eenmaal verplicht om, als er een
const-reference naar een temporary gebruikt wordt als parameter,
te zorgen dat die temporary "lang genoeg" blijft hangen.
Denk maar aan het meer vertrouwde
void blabla (const std::string &s);
blabla ("yup");
Je kan die gimme zien als een "conversie" die van niks
een Blaat maakt... Trouwens, of de copy c'tor nu aangeroepen
wordt of niet, het mysterie van de bytes wordt er niet minder
op : gezien het feit dat bliep een const Blaat& als argument
heeft, naar waar zou er dan eigenlijk gekopieerd worden ?
Antwoord : eveneens naar een onzichtbare Blaat die eventjes snel
wordt gealloceerd zodat bliep er een const& van kan krijgen.
De compiler heeft meer opties dan "heap of stack" :^)
In die zin klopt het dat er een kopie buiten
"de normale ruimte van de functie" (dwz de stack) wordt
gemaakt -- waar het om gaat is dat de copy constructor
daar niet voor (mag) gebruikt worden, enkel compiler magic.
Bert
Re: [C++] function overloading en typedef
Author: Nicolas Barbier
Date: Thu, 29 May 2003 11:03
Date: Thu, 29 May 2003 11:03
83 lines
4098 bytes
4098 bytes
Bert Peers wrote:
> Nicolas Barbier wrote:
>
>> Bert Peers wrote:
>>
>>>Maar dan nog weet ik niet of dit helpt -- de copy constructor wordt
>>>aangeroepen op het moment dat de return value van de functie in de
>>>"recipient" terecht komt.Als die recipient enkel een const& nodig heeft,
>>>moet er niks gekopieerd worden. Ik zou zelfs bijna zeker zeggen,
>>>"..._mag_ er niks gekopieerd worden".
>>
>> Ben je daar zeker van? Je bedoelt dus dan in dit geval de
>> copy-constructur niet opgeroepen mag worden? Ik dacht altijd (puttende
>> uit mijn absoluut onbenullige C++ kennis :-) dat hij altijd wordt
>> aangeroepen als je een volledig object returnt uit een functie. Trouwens,
>> waar zouden, bij een gemiddelde compiler, anders de bytes van het object
>> blijven staan?
>
> Wel, de compiler is nu eenmaal verplicht om, als er een
> const-reference naar een temporary gebruikt wordt als parameter,
> te zorgen dat die temporary "lang genoeg" blijft hangen.
>
> Denk maar aan het meer vertrouwde
>
> void blabla (const std::string &s);
> blabla ("yup");
>
> Je kan die gimme zien als een "conversie" die van niks
> een Blaat maakt... Trouwens, of de copy c'tor nu aangeroepen
> wordt of niet, het mysterie van de bytes wordt er niet minder
> op : gezien het feit dat bliep een const Blaat& als argument
> heeft, naar waar zou er dan eigenlijk gekopieerd worden ?
> Antwoord : eveneens naar een onzichtbare Blaat die eventjes snel
> wordt gealloceerd zodat bliep er een const& van kan krijgen.
>
> De compiler heeft meer opties dan "heap of stack" :^)
> In die zin klopt het dat er een kopie buiten
> "de normale ruimte van de functie" (dwz de stack) wordt
> gemaakt -- waar het om gaat is dat de copy constructor
> daar niet voor (mag) gebruikt worden, enkel compiler magic.
Ik leer weer bij over de semantiek van C++ :-).
/* test.cpp */
#include <iostream>
class Blaat {
public:
Blaat(int i) {
std::cout << "constructor" << std::endl;
}
Blaat(const Blaat &b) {
std::cout << "copy constructor" << std::endl;
}
static Blaat gimme() {
return Blaat(3);
}
};
int main()
{
Blaat a(Blaat::gimme());
std::cout << "tussen a en b" << std::endl;
Blaat b(a);
}
/* uitvoer */
constructor
tussen a en b
copy constructor
De semantiek van een functie die een object returnt is dus blijkbaar niet
"kopieer het te returnen object (via de copy constructor) naar de
ontvangende temporary van de aanroepende functie", maar eerder "de
ontvangende temporary van de aanroepende functie is hetzelfde object als
hetgeen gereturnd wordt".
Weet je toevallig ook nog waarom er geen copy constructor-aanroep gebeurt
tussen "constructor" en "tussen a en b"? :-)
--
Nicolas Barbier
Re: [C++] function overloading en typedef
Author: Slayerke
Date: Thu, 29 May 2003 11:34
Date: Thu, 29 May 2003 11:34
100 lines
4921 bytes
4921 bytes
Nicolas Barbier wrote:
> Bert Peers wrote:
>
>> Nicolas Barbier wrote:
>>
>>> Bert Peers wrote:
>>>
>>>>Maar dan nog weet ik niet of dit helpt -- de copy constructor wordt
>>>>aangeroepen op het moment dat de return value van de functie in de
>>>>"recipient" terecht komt.Als die recipient enkel een const& nodig heeft,
>>>>moet er niks gekopieerd worden. Ik zou zelfs bijna zeker zeggen,
>>>>"..._mag_ er niks gekopieerd worden".
>>>
>>> Ben je daar zeker van? Je bedoelt dus dan in dit geval de
>>> copy-constructur niet opgeroepen mag worden? Ik dacht altijd (puttende
>>> uit mijn absoluut onbenullige C++ kennis :-) dat hij altijd wordt
>>> aangeroepen als je een volledig object returnt uit een functie.
>>> Trouwens, waar zouden, bij een gemiddelde compiler, anders de bytes van
>>> het object blijven staan?
>>
>> Wel, de compiler is nu eenmaal verplicht om, als er een
>> const-reference naar een temporary gebruikt wordt als parameter,
>> te zorgen dat die temporary "lang genoeg" blijft hangen.
>>
>> Denk maar aan het meer vertrouwde
>>
>> void blabla (const std::string &s);
>> blabla ("yup");
>>
>> Je kan die gimme zien als een "conversie" die van niks
>> een Blaat maakt... Trouwens, of de copy c'tor nu aangeroepen
>> wordt of niet, het mysterie van de bytes wordt er niet minder
>> op : gezien het feit dat bliep een const Blaat& als argument
>> heeft, naar waar zou er dan eigenlijk gekopieerd worden ?
>> Antwoord : eveneens naar een onzichtbare Blaat die eventjes snel
>> wordt gealloceerd zodat bliep er een const& van kan krijgen.
>>
>> De compiler heeft meer opties dan "heap of stack" :^)
>> In die zin klopt het dat er een kopie buiten
>> "de normale ruimte van de functie" (dwz de stack) wordt
>> gemaakt -- waar het om gaat is dat de copy constructor
>> daar niet voor (mag) gebruikt worden, enkel compiler magic.
>
> Ik leer weer bij over de semantiek van C++ :-).
>
> /* test.cpp */
> #include <iostream>
>
> class Blaat {
> public:
> Blaat(int i) {
> std::cout << "constructor" << std::endl;
> }
> Blaat(const Blaat &b) {
> std::cout << "copy constructor" << std::endl;
> }
> static Blaat gimme() {
> return Blaat(3);
> }
> };
>
> int main()
> {
> Blaat a(Blaat::gimme());
> std::cout << "tussen a en b" << std::endl;
> Blaat b(a);
> }
>
> /* uitvoer */
> constructor
> tussen a en b
> copy constructor
>
> De semantiek van een functie die een object returnt is dus blijkbaar niet
> "kopieer het te returnen object (via de copy constructor) naar de
> ontvangende temporary van de aanroepende functie", maar eerder "de
> ontvangende temporary van de aanroepende functie is hetzelfde object als
> hetgeen gereturnd wordt".
>
> Weet je toevallig ook nog waarom er geen copy constructor-aanroep gebeurt
> tussen "constructor" en "tussen a en b"? :-)
>
g++ heeft deze al weggeoptimaliseerd, dit moet expliciet afgezet worden:
-fno-elide-constructors
The C++ standard allows an implementation to omit creating a
tempo-
rary which is only used to initialize another object of the same
type. Specifying this option disables that optimization, and
forces G++ to call the copy constructor in all cases.
Dan geeft het (zoals verwacht):
constructor
copy constructor
copy constructor
tussen a en b
copy constructor
--
Groeten,
Slayerke
Re: [C++] function overloading en typedef
Author: Nicolas Barbier
Date: Thu, 29 May 2003 11:57
Date: Thu, 29 May 2003 11:57
30 lines
2146 bytes
2146 bytes
Slayerke wrote: > Nicolas Barbier wrote: (snip) >> Weet je toevallig ook nog waarom er geen copy constructor-aanroep gebeurt >> tussen "constructor" en "tussen a en b"? :-) > > g++ heeft deze al weggeoptimaliseerd, dit moet expliciet afgezet worden: > -fno-elide-constructors > The C++ standard allows an implementation to omit creating a > tempo- > rary which is only used to initialize another object of the > same > type. Specifying this option disables that optimization, and > forces G++ to call the copy constructor in all cases. > Dan geeft het (zoals verwacht): > constructor > copy constructor > copy constructor > tussen a en b > copy constructor *Aaaargl*, ik snap het. Ik moet gewoon de standaard lezen als ik de volledige semantiek van C++ wil kennen. Maar die wil begint weer snel af te brokkelen als ik dergelijke dingen zie ;-). -- Nicolas Barbier
Re: [C++] function overloading en typedef
Author: Bert Peers
Date: Thu, 29 May 2003 13:38
Date: Thu, 29 May 2003 13:38
28 lines
2088 bytes
2088 bytes
Bert wrote: >>>>>Als die recipient enkel een const& nodig heeft, >>>>>moet er niks gekopieerd worden. Slayerke wrote: > -fno-elide-constructors > > Dan geeft het (zoals verwacht): > constructor > copy constructor > copy constructor > tussen a en b > copy constructor > Asjemenou ! 6.6.3.2 : A return statement can involve the construction and copy of a temporary object. Daar wordt een mens niet wijzer van.. Misschien bedoelt men met die "can" : "must, tenzij zoals voorzien in 12.8.15"... Nu ja, tnx :) Bert
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads