|
| Constructorer ? Fra : Torben W. Hansen |
Dato : 14-04-03 18:51 |
|
Hej igen,
Er der en nem måde at huske de forskellige former for constructorer på - og
hvornår samt hvordan de virker ?
(jeg er selvfølgelig klar over at kaldes ved oprettelsen af et objekt)
Jeg har stiftet bekendskab med nedenstående constructorer, som jeg har fået
opfattelsen af virker på følgende måde:
1. Standard-constructor:
Parameterløs constructor, der genereres automatisk af compiler i tilfælde af
at ingen anden standard-constructor er explicit implementeret.
2. Constructor med parametre:
Overloader standard-constructor og kaldes eksempelvis ved: klasse
objekt("HEJ ");
3. Copy-constructor:
Kaldes ved oprettelse af midlertidig kopi af et objekt f.eks. ved
parameteroverførsel til, eller som returværdi fra funktioner.
Copy-constructor har een parameter, der er en reference til et objekt af
samme klasse, f.eks.: klasse(const klasse& rhs);
4. Konverteringsoperator:
Hvis man forsøger at tildele en type (f.eks. int) til et objekt og der
findes en constructor som tager en int-parameter med hvilken den
initialiserer en af objektets variable, så kaldes denne constructor for en
konverteringsoperator. (Det var vist dette, som Byrial J. engang forklarede
mig.)
Korrektioner, kommentarer samt uddybning mm. er meget velkommen....
På forhånd tak...
Med venlig hilsen
Toreben W. Hansen
| |
Ivan Johansen (14-04-2003)
| Kommentar Fra : Ivan Johansen |
Dato : 14-04-03 19:57 |
|
Torben W. Hansen wrote:
> Er der en nem måde at huske de forskellige former for constructorer på - og
> hvornår samt hvordan de virker ?
Det kommer med øvelsen.
> Jeg har stiftet bekendskab med nedenstående constructorer, som jeg har fået
> opfattelsen af virker på følgende måde:
>
> 1. Standard-constructor:
> Parameterløs constructor, der genereres automatisk af compiler i tilfælde af
> at ingen anden standard-constructor er explicit implementeret.
Næsten korrekt. En standard (default) constructor er en constructor som
kan kaldes uden parametre. Dvs. At den enten ikke deklarerer nogen
parametre eller at parametrene har default-værdier. Compileren laver kun
en default constructor hvis du ikke deklarerer nogen form for
constructor, og altså ikke kun en default constructor.
> 2. Constructor med parametre:
> Overloader standard-constructor og kaldes eksempelvis ved: klasse
> objekt("HEJ ");
Korrekt. Bruges hvis du ønsker at initialisere objektet med en eller
flere værdier.
> 3. Copy-constructor:
> Kaldes ved oprettelse af midlertidig kopi af et objekt f.eks. ved
> parameteroverførsel til, eller som returværdi fra funktioner.
> Copy-constructor har een parameter, der er en reference til et objekt af
> samme klasse, f.eks.: klasse(const klasse& rhs);
Det er næsten rigtigt. Constructoren bruges generelt til at lave kopier
af objektet, ikke kun midlertidige. Compileren laver en, hvis du ikke
selv deklarerer en for klassen.
> 4. Konverteringsoperator:
> Hvis man forsøger at tildele en type (f.eks. int) til et objekt og der
> findes en constructor som tager en int-parameter med hvilken den
> initialiserer en af objektets variable, så kaldes denne constructor for en
> konverteringsoperator. (Det var vist dette, som Byrial J. engang forklarede
> mig.)
En konverteringsoperator er noget helt andet, som man for øvrigt bør
holde sig fra. En constructor til konvertering er en ganske almindelig
constructor med parametre, som din constructor nr. 2, med den
begrænsning at den kun har én paramter og ikke er erklæret explicit.
Ivan Johansen
| |
Torben W. Hansen (14-04-2003)
| Kommentar Fra : Torben W. Hansen |
Dato : 14-04-03 20:45 |
|
"Ivan Johansen" <NG2@Padowan.dk> skrev i en meddelelse
news:3E9B0492.8070902@Padowan.dk...
> Det kommer med øvelsen.
OK - så glæder jeg mig til at jeg får øvelsen...
> Næsten korrekt. En standard (default) constructor er en constructor som
> kan kaldes uden parametre. Dvs. At den enten ikke deklarerer nogen
> parametre eller at parametrene har default-værdier. Compileren laver kun
> en default constructor hvis du ikke deklarerer nogen form for
> constructor, og altså ikke kun en default constructor.
OK - dvs. at formulering 1. og 3. kunne være:
1. Standard-constructor:
Er en constructor der kan kaldes uden parametre (dvs. parameterløs eller med
default-parametre). Compiler genererer automatisk en parameterløs
standard-constructor i tilfælde af at ingen anden constructor er explicit
implementeret.
3. Copy-constructor:
Kaldes ved oprettelse af kopi af et objekt f.eks. ved parameteroverførsel
til, eller som returværdi fra funktioner.
Copy-constructor har een parameter, der er en reference til et objekt af
samme klasse, f.eks.: klasse(const klasse& rhs);
> En konverteringsoperator er noget helt andet, som man for øvrigt bør
> holde sig fra. En constructor til konvertering er en ganske almindelig
> constructor med parametre, som din constructor nr. 2, med den
> begrænsning at den kun har én paramter og ikke er erklæret explicit.
Men er en constructor med én parameter da ikke altid erklæret explicit ?
Med venlig hilsen
Torben W. Hansen
| |
Ivan Johansen (14-04-2003)
| Kommentar Fra : Ivan Johansen |
Dato : 14-04-03 21:43 |
|
Torben W. Hansen wrote:
> OK - dvs. at formulering 1. og 3. kunne være:
>
> 1. Standard-constructor:
> Er en constructor der kan kaldes uden parametre (dvs. parameterløs eller med
> default-parametre). Compiler genererer automatisk en parameterløs
> standard-constructor i tilfælde af at ingen anden constructor er explicit
> implementeret.
Ja, bortset fra at du skal skifte "implementeret" ud med "deklareret".
> 3. Copy-constructor:
> Kaldes ved oprettelse af kopi af et objekt f.eks. ved parameteroverførsel
> til, eller som returværdi fra funktioner.
> Copy-constructor har een parameter, der er en reference til et objekt af
> samme klasse, f.eks.: klasse(const klasse& rhs);
Ja, det er korrekt.
> Men er en constructor med én parameter da ikke altid erklæret explicit ?
Jeg var vist lidt uklar her. Jeg hentyder til nøgleordet "explicit" i
C++. Lad os tage et eksempel:
Du har en funktion f, der tager et objekt af klassen C som parameter:
void f(const C&);
Klassen C er defineret således:
class C
{
public:
explicit C(int);
C(double);
};
Du laver nu to funktionskald:
f(10.0); //Virker
f(10); //Fejl
Det første virker, fordi 10.0 er af typen double. Constructoren
C(double) bruges til at konvertere tallet til et objekt af typen C, som
kan bruges som argument til funktionen f.
Det andet funktionskald duer ikke, fordi 10 er af typen int, men
constructoren C(int) er erklæret med nøgleordet "explicit". Den
automatiske konvertering til C kan derfor ikke lade sig gøre for int.
Konverteringen skal derfor angives eksplicit:
f(C(10));
Nøgleordet "explicit" er dog ikke voldsomt meget brugt.
Jeg håber det var mere forståeligt.
Ivan Johansen
| |
Torben W. Hansen (14-04-2003)
| Kommentar Fra : Torben W. Hansen |
Dato : 14-04-03 22:30 |
|
"Ivan Johansen" <NG2@Padowan.dk> skrev i en meddelelse
news:3E9B1D71.7070801@Padowan.dk...
>
> Nøgleordet "explicit" er dog ikke voldsomt meget brugt.
>
> Jeg håber det var mere forståeligt.
Helt bestemt - jeg kendte slet ikke nøgleordet "explicit".
Hvis constructoren "explicit C(int)" i dit eksempel var udeladt, ville
kaldet "f(10);" så have virket ?
Man kunne måske forestille sig at "f(10);" automatisk ville blive castet til
"f(10.0)" ligesom "float tal =10;"
Med venlig hilsen
Torben W. Hansen
| |
Ivan Johansen (15-04-2003)
| Kommentar Fra : Ivan Johansen |
Dato : 15-04-03 07:12 |
|
Torben W. Hansen wrote:
> Hvis constructoren "explicit C(int)" i dit eksempel var udeladt, ville
> kaldet "f(10);" så have virket ?
>
> Man kunne måske forestille sig at "f(10);" automatisk ville blive castet til
> "f(10.0)" ligesom "float tal =10;"
Ja, det er helt korrekt.
Ivan Johansen
| |
Flare (15-04-2003)
| Kommentar Fra : Flare |
Dato : 15-04-03 21:11 |
|
> > Hvis constructoren "explicit C(int)" i dit eksempel var udeladt, ville
> > kaldet "f(10);" så have virket ?
> >
> > Man kunne måske forestille sig at "f(10);" automatisk ville blive castet
til
> > "f(10.0)" ligesom "float tal =10;"
Nu skal jeg lige være med.
class foo
{
foo(int u)
{}
foo(double u)
{}
foo(char u)
{}
}
Her laves da parameter overloading, idet parameteren "vælger" den rigtige
konstruktor.
Mvh
Anders
| |
Torben W. Hansen (15-04-2003)
| Kommentar Fra : Torben W. Hansen |
Dato : 15-04-03 22:32 |
|
"Flare" <dct_flare@hotmail.com> skrev i en meddelelse
news:3e9c676b$0$185$edfadb0f@dread15.news.tele.dk...
> Nu skal jeg lige være med.
>
> class foo
> {
> foo(int u)
> {}
>
> foo(double u)
> {}
>
> foo(char u)
> {}
> }
>
> Her laves da parameter overloading, idet parameteren "vælger" den rigtige
> konstruktor.
Ja - men sådan som jeg forstår Ivans forklaring vil det ikke være tilfældet
nedenfor:
class foo
{
foo(int u)
{}
explicit foo(double u) // erklæret explicit
{}
explicit foo(char u) // erklæret explicit
{}
}
void f(const foo&){...}
int main()
{
int intValue;
double doubleValue;
char charValue;
f(intValue); // OK
f(doubleValue); // virker ikke pga. nøgleordet "explicit" ovenfor
f(foo(doubleValue)); // OK da konvertering skal angives explicit
f(charValue); // virker ikke pga. nøgleordet "explicit" ovenfor
f(foo(charValue)); // OK da konvertering skal angives explicit
return 0;
}
| |
Ivan Johansen (16-04-2003)
| Kommentar Fra : Ivan Johansen |
Dato : 16-04-03 07:27 |
|
Torben W. Hansen wrote:
> f(doubleValue); // virker ikke pga. nøgleordet "explicit" ovenfor
Jeg er bange for at jeg var lidt for hurtig med mit svar. Jeg har lige
prøvet det af og det giver ikke en fejl, som jeg ellers sagde. Men
compileren bruge den constructor der ikke er erklæret med "explicit",
dvs. foo(int). doubleValue vil altså automatisk blive konverteret til en
int. Så man skal lige være opmærksom på at der her er forskel på hvilken
constructor der anvendes afhængig af om konverteringen angives eksplicit
eller ej.
Ivan Johansen
| |
Torben W. Hansen (16-04-2003)
| Kommentar Fra : Torben W. Hansen |
Dato : 16-04-03 08:05 |
|
"Ivan Johansen" <NG2@Padowan.dk> skrev i en meddelelse
news:3E9CF7AC.40007@Padowan.dk...
> Jeg er bange for at jeg var lidt for hurtig med mit svar. Jeg har lige
.....
OK - jeg prøver lige selv at lege lidt med eksemplet...
Med venlig hilsen
Torben W. Hansen
| |
Torben W. Hansen (15-04-2003)
| Kommentar Fra : Torben W. Hansen |
Dato : 15-04-03 22:10 |
|
"Ivan Johansen" <NG2@Padowan.dk> skrev i en meddelelse
news:3E9BA2B1.50409@Padowan.dk...
> > Man kunne måske forestille sig at "f(10);" automatisk ville blive castet
til
> > "f(10.0)" ligesom "float tal =10;"
>
> Ja, det er helt korrekt.
Jeg siger mange tak for din hjælp Ivan,
- og så blev jeg lidt klogere...
Med venlig hilsen
Torben W. Hansen
| |
|
|