/ 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
C/C++: 2 om klasser
Fra : Klaus Petersen


Dato : 27-01-03 17:31

Hej NG.

Jeg har 2 problemer, som jeg lige ville høre Jer ad om i kender en løsning
på (jeg bruger Visual C++ 6.0).

Problem 1:

Hvis man nu har en klasse a lá:

class A
{
public:
B readonly;
};

Hvorledes kan jeg lave den property (readonly) til at være readonly - dvs.
at man ikke kan tildele den en ny værdi selvom den er erklæret public?

Det perfekte ville være, at den gav en fejlmeddelse hvis man prøvede på det.

Problem 2:

Betragt følgende kode:

class A
{
private:
B info;
};

class B
{
private:
A info;
}

Problemet er, at class A skal kende class B og omvendt. Det er i øvrigt med
vilje, at jeg ikke laver dem som pointere, da klasserne kommer til at skulle
kalde metoder på objekterne.

Kan i hjælpe med en evt. løsning?



 
 
Ruben Nørgaard (27-01-2003)
Kommentar
Fra : Ruben Nørgaard


Dato : 27-01-03 18:03

> Problem 1:
> Hvis man nu har en klasse a lá:
> class A
> {
> public:
> B readonly;
> };
>
> Hvorledes kan jeg lave den property (readonly) til at være readonly - dvs.
> at man ikke kan tildele den en ny værdi selvom den er erklæret public?

En variabel kan ikke være readonly i C++. Du kan istedet bruge #define eller
const værdier. Disse sættes så på kompile tidspunkt.
Hvis det er en variabel som skal sættes én gang runtime, så bør du bruge
funktioner til at styre det

f.eks.

class A
{
B
private:
GetValueB()
SetValueB( ... )
}

> Problem 2:
> Betragt følgende kode:
> class A
> {
> private:
> B info;
> };
>
> class B
> {
> private:
> A info;
> }
>

Kan man ikke.. brug pointere istedet du kan godt opnå den samme
funktionalitet alligevel.

mvh Ruben Nørgaard



Bertel Lund Hansen (27-01-2003)
Kommentar
Fra : Bertel Lund Hansen


Dato : 27-01-03 18:13

Ruben Nørgaard skrev:

>Hvis det er en variabel som skal sættes én gang runtime, så bør du bruge
>funktioner til at styre det

>f.eks.

>class A
>{
> B
> private:
> GetValueB()
> SetValueB( ... )
>}

Hellere:

class A
{
public:
sometype GetValueB() { return B; }
private:
sometype B;
void SetValueB( ... ) {...};
};

Det giver readonly-funktionaliteten.

--
Bertel
http://bertel.lundhansen.dk/   FIDUSO: http://fiduso.dk/

Ruben Nørgaard (27-01-2003)
Kommentar
Fra : Ruben Nørgaard


Dato : 27-01-03 18:19

Ja klart...
Det var vist noget rod jeg fik lavet med private / public parametrene..

mvh Ruben Nørgaard
http://www.rubennoergaard.dk


"Bertel Lund Hansen" <nospamfor@lundhansen.dk> wrote in message
news:41qa3vspm7evjs8vojntfamodmbme7vsc3@news.stofanet.dk...
> Ruben Nørgaard skrev:
>
> >Hvis det er en variabel som skal sættes én gang runtime, så bør du bruge
> >funktioner til at styre det
>
> >f.eks.
>
> >class A
> >{
> > B
> > private:
> > GetValueB()
> > SetValueB( ... )
> >}
>
> Hellere:
>
> class A
> {
> public:
> sometype GetValueB() { return B; }
> private:
> sometype B;
> void SetValueB( ... ) {...};
> };
>
> Det giver readonly-funktionaliteten.
>
> --
> Bertel
> http://bertel.lundhansen.dk/ FIDUSO: http://fiduso.dk/



Mogens Hansen (27-01-2003)
Kommentar
Fra : Mogens Hansen


Dato : 27-01-03 20:15


"Bertel Lund Hansen" <nospamfor@lundhansen.dk> wrote

> Hellere:
>
> class A
> {
> public:
> sometype GetValueB() { return B; }

Hellere:
const sometype& GetValueB() const;

Man undgår at lave en overflødig kopi, som muligvis kan være dyrt.
Man undgår at kræve at det skal muligt at lave en kopi af "sometype".
Man kan kalde GetValueB, hvis man har et "const A" objekt.

Venlig hilsen

Mogens Hansen



Mogens Hansen (27-01-2003)
Kommentar
Fra : Mogens Hansen


Dato : 27-01-03 20:15


"Ruben Nørgaard" <nospam@nospam.spam> wrote

> > Problem 1:
> > Hvis man nu har en klasse a lá:
> > class A
> > {
> > public:
> > B readonly;
> > };
> >
> > Hvorledes kan jeg lave den property (readonly) til at være readonly -
dvs.
> > at man ikke kan tildele den en ny værdi selvom den er erklæret public?
>
> En variabel kan ikke være readonly i C++.

Hvorfor ikke ?
Hvad med:

class A
{
public:
// ...
const B readonly;
// ...
};

?

> Du kan istedet bruge #define eller
> const værdier. Disse sættes så på kompile tidspunkt.

Hvad hjælper det ?
Kan du give et godt eksempel ?

Venlig hilsen

Mogens Hansen



Byrial Jensen (27-01-2003)
Kommentar
Fra : Byrial Jensen


Dato : 27-01-03 20:31

Ruben Nørgaard <nospam@nospam.spam> skrev:
>> Problem 1:
>> Hvis man nu har en klasse a lá:
>> class A
>> {
>> public:
>> B readonly;
>> };
>>
>> Hvorledes kan jeg lave den property (readonly) til at være readonly - dvs.
>> at man ikke kan tildele den en ny værdi selvom den er erklæret public?
>
> En variabel kan ikke være readonly i C++.

Det kan den da. Det er det man bruger const til:

class A
{
public:
const B readonly;
[...]
}

Da readonly er konstant, skal den initialiseres i A's constructor.
Her er et komplet program:

class B
{
public:
int i;
B (int b) : i(b) {};
};

class A
{
public:
const B readonly;
A (int b) : readonly(b) {};
};

main ()
{
A a(5);
return a.readonly.i;
}

Byrial Jensen (27-01-2003)
Kommentar
Fra : Byrial Jensen


Dato : 27-01-03 20:38

Byrial Jensen <bjensen@nospam.dk> skrev:

Hov, jeg glemte eksplicit at angive at main's returtype er int. Det
er påkrævet i C++ og i øvrigt også i C99 (men ikke i tidligere
udgaver af C):

int
> main ()
> {
> A a(5);
> return a.readonly.i;
> }

Ruben Nørgaard (27-01-2003)
Kommentar
Fra : Ruben Nørgaard


Dato : 27-01-03 21:36


Du har ret.. med den note at det stadig kun er et kompiler direktiv og
derfor godt kan omgåes rent kodemæssigt.. Den er altså ikke entydig
"readonly".. men sådan er det jo med C/C++. Det meste kan omgåes.

mvh Ruben Nørgaard

"Byrial Jensen" <bjensen@nospam.dk> wrote in message
news:slrnb3b13i.1dj.bjensen@ask.ask...
> Ruben Nørgaard <nospam@nospam.spam> skrev:
> >> Problem 1:
> >> Hvis man nu har en klasse a lá:
> >> class A
> >> {
> >> public:
> >> B readonly;
> >> };
> >>
> >> Hvorledes kan jeg lave den property (readonly) til at være readonly -
dvs.
> >> at man ikke kan tildele den en ny værdi selvom den er erklæret public?
> >
> > En variabel kan ikke være readonly i C++.
>
> Det kan den da. Det er det man bruger const til:
>
> class A
> {
> public:
> const B readonly;
> [...]
> }
>
> Da readonly er konstant, skal den initialiseres i A's constructor.
> Her er et komplet program:
>
> class B
> {
> public:
> int i;
> B (int b) : i(b) {};
> };
>
> class A
> {
> public:
> const B readonly;
> A (int b) : readonly(b) {};
> };
>
> main ()
> {
> A a(5);
> return a.readonly.i;
> }



Mogens Hansen (27-01-2003)
Kommentar
Fra : Mogens Hansen


Dato : 27-01-03 21:44


"Ruben Nørgaard" <nospam@nospam.spam> wrote in message
news:3e3597d7$0$24685$ba624c82@nntp02.dk.telia.net...
>
> Du har ret.. med den note at det stadig kun er et kompiler direktiv og
> derfor godt kan omgåes rent kodemæssigt..

Med garanteret, veldefineret betydning ?
Det kan være at compileren vælger at lægge det steder hvor data faktisk _er_
readonly, som f.eks. ROM eller et readonly segment.

> Den er altså ikke entydig
> "readonly".. men sådan er det jo med C/C++. Det meste kan omgåes.

#define private public
#define const


Venlig hilsen

Mogens Hansen



Bjarke Dahl Ebert (27-01-2003)
Kommentar
Fra : Bjarke Dahl Ebert


Dato : 27-01-03 22:05

"Mogens Hansen" <mogens_h@dk-online.dk> wrote in message

> > Du har ret.. med den note at det stadig kun er et kompiler direktiv og
> > derfor godt kan omgåes rent kodemæssigt..
>
> Med garanteret, veldefineret betydning ?
> Det kan være at compileren vælger at lægge det steder hvor data faktisk
_er_
> readonly, som f.eks. ROM eller et readonly segment.

Mogens, dig og din standard
Man koder ikke mod en standard, man koder mod en C++-implementation (eller
måske flere). En C++-standard kan ikke kompilere programmet, det kan en
C++-implementation.

Hvis en compiler oversætter til kode, der giver veldefineret mening til
const_cast<something&>(a->readonly) = fubar;
så er det stadig en C++-compiler.

Standarden er et sæt *minimums*-specifikationer, som compileren skal
overholde.
I alle de C++-compilere jeg kender, har const kun betydning på compiletime -
det er ikke en "hardware-beskyttelse" af værdien.

Bjarke





Mogens Hansen (27-01-2003)
Kommentar
Fra : Mogens Hansen


Dato : 27-01-03 22:41


"Bjarke Dahl Ebert" <bebert@tiscali.dk> wrote

> I alle de C++-compilere jeg kender, har const kun betydning på
compiletime -
> det er ikke en "hardware-beskyttelse" af værdien.

Har du kigget ordentlig efter ?

Så vidt jeg husker bruger du Microsoft Visual C++ V6.0 (bl.a. ??).
Prøv:

<code>
#include <iostream>

const int i = 8;

int main()
{
using namespace std;

cout << i << endl;
const_cast<int&>(i) = 2;
cout << i << endl;
}
</code>

På min maskine skriver den

G:\cpp\fnyt11\Debug>fnyt11.exe
8

inden der kommer en message-box med

---------------------------
fnyt11.exe - Application Error
---------------------------
The instruction at "0x00401590" referenced memory at "0x0046e01c". The
memory could not be "written".


Click on OK to terminate the program
Click on CANCEL to debug the program
---------------------------
OK Cancel
---------------------------

Intel C++ V5.0 for Windows skriver:

G:\cpp\fnyt11\Debug>fnyt11.exe
8
8

og det samme gør Borland C++Builder V6.0.

Og altsammen er helt i orden.

Venlig hilsen

Mogens Hansen



Ruben Nørgaard (27-01-2003)
Kommentar
Fra : Ruben Nørgaard


Dato : 27-01-03 22:55

Nu har jeg ikke kigget MS C++ efter i sømmene, men i dit tidligere eksempel
med class A og class B kan man godt type caste og rette værdien. Hvilket får
mig til at tro at MS C++ ikke opretter et readonly område til din variabel i
dette eksempel, men blot optimer den om til en #define i 8 og på den måde
putter den ind i kodeblokken som (hvis jeg husker ret) er readonly under
Windows.

Hvis (og jeg siger hvis) mine antagelser er rigtige, så er det altså ikke
fordi at MS C++ laver const variabler readonly, men fordi den optimerer dem
at man ikke kan skrive til dem, hvilket igen betyder at man i praksis ikke
har readonly variabler på codeniveau i C++.

Nå denne diskussion er vist ved at dreje ud på et spor, hvor det ikke
længere har nogen praktisk betydning for det oprindelige spørgsmål, men det
har været hyggeligt.. Jeg vil stoppe nu..

mvh Ruben Nørgaard

"Mogens Hansen" <mogens_h@dk-online.dk> wrote in message
news:b148sr$237b$1@news.cybercity.dk...
>
> "Bjarke Dahl Ebert" <bebert@tiscali.dk> wrote
>
> > I alle de C++-compilere jeg kender, har const kun betydning på
> compiletime -
> > det er ikke en "hardware-beskyttelse" af værdien.
>
> Har du kigget ordentlig efter ?
>
> Så vidt jeg husker bruger du Microsoft Visual C++ V6.0 (bl.a. ??).
> Prøv:
>
> <code>
> #include <iostream>
>
> const int i = 8;
>
> int main()
> {
> using namespace std;
>
> cout << i << endl;
> const_cast<int&>(i) = 2;
> cout << i << endl;
> }
> </code>
>
> På min maskine skriver den
>
> G:\cpp\fnyt11\Debug>fnyt11.exe
> 8
>
> inden der kommer en message-box med
>
> ---------------------------
> fnyt11.exe - Application Error
> ---------------------------
> The instruction at "0x00401590" referenced memory at "0x0046e01c". The
> memory could not be "written".
>
>
> Click on OK to terminate the program
> Click on CANCEL to debug the program
> ---------------------------
> OK Cancel
> ---------------------------
>
> Intel C++ V5.0 for Windows skriver:
>
> G:\cpp\fnyt11\Debug>fnyt11.exe
> 8
> 8
>
> og det samme gør Borland C++Builder V6.0.
>
> Og altsammen er helt i orden.
>
> Venlig hilsen
>
> Mogens Hansen
>
>



Mogens Hansen (27-01-2003)
Kommentar
Fra : Mogens Hansen


Dato : 27-01-03 23:12


"Ruben Nørgaard" <nospam@nospam.spam> wrote in message
news:3e35aa44$0$24692$ba624c82@nntp02.dk.telia.net...
> Nu har jeg ikke kigget MS C++ efter i sømmene, men i dit tidligere
eksempel
> med class A og class B kan man godt type caste og rette værdien.

Ja, men det gælder ikke nødvendigvis.

> Hvilket får
> mig til at tro at MS C++ ikke opretter et readonly område til din variabel
i
> dette eksempel, men blot optimer den om til en #define i 8 og på den måde
> putter den ind i kodeblokken som (hvis jeg husker ret) er readonly under
> Windows.

Du tager så afgjort fejl.

>
> Hvis (og jeg siger hvis) mine antagelser er rigtige, så er det altså ikke
> fordi at MS C++ laver const variabler readonly,

Den lægger globale const variabler af simple typer i et readonly segment.

> men fordi den optimerer dem
> at man ikke kan skrive til dem, hvilket igen betyder at man i praksis ikke
> har readonly variabler på codeniveau i C++.

Du tager fejl - sommetider har man readonly variabler.


Venlig hilsen

Mogens Hansen



Byrial Jensen (28-01-2003)
Kommentar
Fra : Byrial Jensen


Dato : 28-01-03 02:24

Ruben Nørgaard <nospam@nospam.spam> skrev:

> Hvis (og jeg siger hvis) mine antagelser er rigtige, så er det altså ikke
> fordi at MS C++ laver const variabler readonly, men fordi den optimerer dem
> at man ikke kan skrive til dem, hvilket igen betyder at man i praksis ikke
> har readonly variabler på codeniveau i C++.

Jeg aner ikke hvordan MS C++ behandler "const", og det er også
ganske irrelevant for om C++ som sådan har readonly-variabler
eller ej. Det har C++.

Igor V. Rafienko (27-01-2003)
Kommentar
Fra : Igor V. Rafienko


Dato : 27-01-03 23:25

[ Klaus Petersen ]

[ ... ]

> class A
> {
> public:
> B readonly;
> };
>
> Hvorledes kan jeg lave den property (readonly) til at være readonly
> - dvs. at man ikke kan tildele den en ny værdi selvom den er
> erklæret public?
>
> Det perfekte ville være, at den gav en fejlmeddelse hvis man prøvede
> på det.


Et mulig, dog ekstremt klønete, forslag er å lage en type som vil
tjene _kun_ formålet ditt: attributtet som skal være r/o, vil være
nettopp det, men unntaket av A:

template< typename T >
class readonly
{
T value;

readonly& operator=( const readonly &r ){ value = r.value; }
/* I'm not sure this version is appropriate */
T& operator=( const T &t ){ value = t; }
public:
/* All of T's ctors (no other ctors!) */

/* Do we really want a copy? */
operator T(){ return value; }
operator const T&() const { return value; }

friend class A;
};

class A
{
public:
readonly< int > info;

void foo(){ info = 3; }
};


int
main()
{
A a;

a.info = 3; /* error: readonly< int > :: operator=() not accessible */
a.foo(); /* OK: (controlled?) modification through A */

std::cout << a.info << "\n";
}

Bare så det er sagt -- dette er et _tankeeksperiment_, ikke noe mer.
Det å få readonly< T > til å oppføre seg som T selv for lese-tilgang
vil nok være ganske komplisert.

Nå er jeg veldig ustødig i C++ og det kan hende at koden over
inneholder (konseptuelle heller enn syntaktiske) feil som jeg ikke
greier å se. GCC 3.2 svelger dette, men advarer om at den foretrekker
"operator T()" framfor "operator const T&" på siste linje i main.

Nå sier også ESR at en god netiquette er å foreslå skikkelige
løsninger, framfor halvfordøyde "hacks", så jeg er litt usikker på hva
et slikt forslag gjør meg til.

[ ... ]


> class A
> {
> private:
> B info;
> };
>
> class B
> {
> private:
> A info;
> }
>
> Problemet er, at class A skal kende class B og omvendt. Det er i
> øvrigt med vilje, at jeg ikke laver dem som pointere, da klasserne
> kommer til at skulle kalde metoder på objekterne.
>
> Kan i hjælpe med en evt. løsning?


Jada, du kan godt få en løsning. Under _en_ forutsetning -- beskriv
_eksakt_ hvordan en instans av A og en instans av B skal kunne
opprettes (dagens stikkord: infinite recursion).

Jeg tror[tm] C++'isk måte å gjøre det på er via pekere.





ivr
--
<peder> igorr: tcl ja... det er fra de dypeste avgrunnene i helvete det...
<peder> php er bare fra foajeen
            -- pederst på irc

Søg
Reklame
Statistik
Spørgsmål : 177491
Tips : 31966
Nyheder : 719565
Indlæg : 6408458
Brugere : 218886

Månedens bedste
Årets bedste
Sidste års bedste