/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
member initialisering af nedarvede members~
Fra : Klaus Hebsgaard


Dato : 12-01-06 16:00

Hej

Jeg opdagede lige noget mærkeligt idag - tror jeg nok.

I C++ er det ikke lovligt at gøre følgende:

class base

{

public:

base(){};

protected:

int myprotmember;

};

class inherited : public base

{

public:

inherited():base(), myprotmember(1){};

};

Det der er problemet er at compileren ikke vil kendes ved at myprotmember er
medlem af inherited.
Fint nok tænkte jeg så prefixer jeg den bare med base:: men det giver samme
fejl.

Der er sikkert en helt logisk forklaring på det, men hvad er forklaringen?

På forhånd tak.

Klaus Hebsgaard



 
 
Mogens Hansen (12-01-2006)
Kommentar
Fra : Mogens Hansen


Dato : 12-01-06 16:36


"Klaus Hebsgaard" <klaus-fjern-dette@no.spamhebsgaard.dk> wrote in message
news:43c66ee7$0$1845$edfadb0f@dread11.news.tele.dk...

[8<8<8<]
> Der er sikkert en helt logisk forklaring på det, men hvad er forklaringen?

Der er en væsentlig skelnen mellem initialisering og tildeling (assignment).
Når constructor eksekveringen når til "inherited"'s constructor er "base"
objektet fuldstændigt initialiseret. Det betyder at "myprotmember" er fuldt
initialiseret og derfor ikke kan initialiseres igen.

Det du skal skrive er

class base
{
// ...
protected: // optional - might be public
base(int myprotmember_init_value) :
myprotmember(myprotmember_init_value) {}
// ...
};

class derived : public base
{
public:
derived() :
base(1) {}
};

For fuldstændighedens skyld skal det bemærkes at virtuelle base klasser
altid bliver initialiseret fra den mest afledte klasse. (Hvis det ikke
umiddelbart ringer en klokke hos dig, så fortvivl ikke - det er noget man
sjældent bruger)

Venlig hilsen

Mogens Hansen



Klaus Hebsgaard (12-01-2006)
Kommentar
Fra : Klaus Hebsgaard


Dato : 12-01-06 21:38


"Mogens Hansen" <mogens_h@dk-online.dk> skrev i en meddelelse
news:43c67754$0$67258$157c6196@dreader2.cybercity.dk...
>
> "Klaus Hebsgaard" <klaus-fjern-dette@no.spamhebsgaard.dk> wrote in message
> news:43c66ee7$0$1845$edfadb0f@dread11.news.tele.dk...
>
> [8<8<8<]
>> Der er sikkert en helt logisk forklaring på det, men hvad er
>> forklaringen?
>
> Der er en væsentlig skelnen mellem initialisering og tildeling
> (assignment).
> Når constructor eksekveringen når til "inherited"'s constructor er "base"
> objektet fuldstændigt initialiseret. Det betyder at "myprotmember" er
> fuldt initialiseret og derfor ikke kan initialiseres igen.

OK, i dette tilfælde er der vist ikke den store forskel på initialisering og
tildeling, er der eksempler hvor det er tydeligt at der er en forskel på
tildeling og initialisering? Og hvorfor denne skelnen?

>
> Det du skal skrive er
>
> class base
> {
> // ...
> protected: // optional - might be public
> base(int myprotmember_init_value) :
> myprotmember(myprotmember_init_value) {}
> // ...
> };
>
> class derived : public base
> {
> public:
> derived() :
> base(1) {}
> };

OK, det giver jo meget god mening, når engang jeg får hittet rede på
forskellen på initialisering og tildeling...


>
> For fuldstændighedens skyld skal det bemærkes at virtuelle base klasser
> altid bliver initialiseret fra den mest afledte klasse. (Hvis det ikke
> umiddelbart ringer en klokke hos dig, så fortvivl ikke - det er noget man
> sjældent bruger)
>

OK.

> Venlig hilsen
>
> Mogens Hansen
>

Tak



Mogens Hansen (12-01-2006)
Kommentar
Fra : Mogens Hansen


Dato : 12-01-06 22:50


"Klaus Hebsgaard" <kh@sletdetteingenioer.dk> wrote in message
news:43c6be15$0$38650$edfadb0f@dread12.news.tele.dk...

[8<8<8<]
> OK, i dette tilfælde er der vist ikke den store forskel på initialisering
> og tildeling, er der eksempler hvor det er tydeligt at der er en forskel
> på tildeling og initialisering?

Et simpelt eksempel, hvis du ændrer din kode en lille smule:

class base
{
protected:
base(int i_init_value) :
i(i_init_value) {}

const int i;
};

Så er "i" konstant og kan ikke tildeles (med mindre man caster const væk).
Dens værdi skal derfor etableres når det oprettes.
For referencer gælder det altid at de skal initialiseres og aldrig senere
kan tildeles en ny værdi.

> Og hvorfor denne skelnen?


Initialisering er processen hvor man går fra ingenting (rå hukommelse) til
et gyldigt objekt. Den process varetages af constructoren.
Tildeling er processen hvor et objekt går fra een gyldig tilstand til en
anden gyldig tilstand. Den process varetages af assignment operatoren.

Det er langt fra alle typer hvor tildeling giver mening. Det gælder ofte for
klasser i et klasse hieraki.
Tildeling giver mening på typer der har værdi semantik som f.eks. "int",
"std::string", "std::complex" og dato typer. De kan frit (og ofte billigt)
tildeles og kopieres.
Typer med stærk identitet (f.eks. en bank konto objekt eller person objekt)
kan ikke frit kopieres og tildeles. Selv om de har samme værdi (ingen penge
på kontoen eller samme navn) er det væsentligt at skelne det ene objekt fra
det andet (din tomme konto og min tomme konto).
Men det giver for alle typer mening at initialisere dem.


Venlig hilsen

Mogens Hansen



Klaus Hebsgaard (13-01-2006)
Kommentar
Fra : Klaus Hebsgaard


Dato : 13-01-06 11:12

Tusind tak Mogens

Jeg blev godt nok en hel del klogere her

MVH
Klaus



Thorsten Ottosen (12-01-2006)
Kommentar
Fra : Thorsten Ottosen


Dato : 12-01-06 16:38

Klaus Hebsgaard wrote:
> Hej
>
> Jeg opdagede lige noget mærkeligt idag - tror jeg nok.
>
> I C++ er det ikke lovligt at gøre følgende:
>
> class base
>
> {
>
> public:
>
> base(){};
>
> protected:
>
> int myprotmember;
>
> };
>
> class inherited : public base
>
> {
>
> public:
>
> inherited():base(), myprotmember(1){};
>
> };
>
> Det der er problemet er at compileren ikke vil kendes ved at myprotmember er
> medlem af inherited.
> Fint nok tænkte jeg så prefixer jeg den bare med base:: men det giver samme
> fejl.
>
> Der er sikkert en helt logisk forklaring på det, men hvad er forklaringen?

Initialiser member variable i den classe, de defineres i. Du kan evt
initialisere variable i kroppen på konstruktoren.

-Thorsten


Mogens Hansen (12-01-2006)
Kommentar
Fra : Mogens Hansen


Dato : 12-01-06 17:09

Hej Thorsten,


"Thorsten Ottosen" <thorsten.ottosen@dezide.com> wrote in message
news:43c677d4$0$78285$157c6196@dreader1.cybercity.dk...

[8<8<8<]
> Du kan evt initialisere variable i kroppen på konstruktoren.

Jeg antager at du mener tildele i stedet for initialisere.

Venlig hilsen

Mogens Hansen



Thorsten Ottosen (12-01-2006)
Kommentar
Fra : Thorsten Ottosen


Dato : 12-01-06 17:36

Mogens Hansen wrote:
> Hej Thorsten,
>
>
> "Thorsten Ottosen" <thorsten.ottosen@dezide.com> wrote in message
> news:43c677d4$0$78285$157c6196@dreader1.cybercity.dk...
>
> [8<8<8<]
>
>>Du kan evt initialisere variable i kroppen på konstruktoren.
>
>
> Jeg antager at du mener tildele i stedet for initialisere.

yes, tak for rettelsen. Jeg vender mig aldrig til en dansk terminologi

-Thorsten

Søg
Reklame
Statistik
Spørgsmål : 177577
Tips : 31968
Nyheder : 719565
Indlæg : 6409071
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste