effektivt klassedesign med static members?

Tags:    c++

Hej udviklere,

jeg sidder med et program der skal holde styr på nogle fuglearter på et landkort. Kortet (og arterne) har jeg modelleret som et kvadrat-'grid', dvs en vector<vector<int> >.

Mit problem er at alle arterne skal bruge det samme landkort, men har hver deres udbredelseskort. Jeg har prøvet at implementere det sådan her:
Fold kodeboks ind/udKode 

(jeg har kun medtaget de vigtigste linier). Mit håb var så at hvis jeg startede med at initialisere Map (med kortfilen), så ville de variabel-værdier jeg skulle bruges nedarves til hver Species, idet de var erklæret static.
Det virker dog tilsyneladende ikke - jeg får compile-error: "undefined reference to x_size". Er det den forkerte måde rent OOP-teknisk jeg har valgt at gribe det an? Hvordan kunne jeg ellers få den ønskede virkning?
Jeg kunne vel lave dem som to adskilte klasser, og så kun lave en instans a map-klassen. Men så ville species-objektet jo skulle spørge map-objektet hver eneste gang han skulle vide om et felt var beboeligt eller ej, og det virker lidt kluntet...




10 svar postet i denne tråd vises herunder
1 indlæg har modtaget i alt 2 karma
Sorter efter stemmer Sorter efter dato
Hmm... jeg vill nok ikke vælge at nedarve species fra map. Det er måske bare mig, men rent logisk giver det ikke mening for mig at en fugleart er en specialisering af et kort. Jeg ville hellere lave en liste af species på map og så have de andre eventuelle properties og funktioner på hver sin klasse. Jeg synes bare ikke det giver mening med en nedarvning. Og så en ide: Så vidt jeg ved er det lige ud ad landevejen at lave et koordinatsystem, tilsvarende det man ville se på et kort eller en GPS. Så hvis man kendte koordinatet hvor kortet startede (øverste venstre hjørne) og hvor stort kortet var, ville man kunne plotte GPS værdier m.v. direkte derind på. Samtidig ville det være muligt at sætte flere kort sammen (så kan du ikke have static properties, da det ikke ville give mening at dele dem på tværs af alle kort, mit råd allerede uden det er at droppe dem som static)

Held og lykke med det :-)

/Brian



når de er statiske skal du lige huske også at sætte en værdi på. Se mit eksempel,

Fold kodeboks ind/udKode 


Har du gjort det?



Martin >> Nej, det har jeg ikke gjort, jeg vidste ikke det var nødvendigt - og det var årsagen til mine fejlmeddelelser. Tak! Min umiddelbare intuition ville have været at bruge en initialization list, men det virker tilsyneladende ikke.

Brian >> Nej du har på en måde ret, jeg kan bare ikke gennemskue hvad der er den bedste måde at designe det på OOP. Så vidt jeg kan forstå foreslår du:
Fold kodeboks ind/udKode 

Problemet er Species helst skal kende kortet; f.eks. når jeg udskriver, kalder jeg:
Fold kodeboks ind/udKode 

Dvs species skal kende Map::domain. Jeg kan ikke gennemskue hvordan en Species kan kende en værdi af en klasse den er en del af? hvis jeg skrev 'map.domain' kan jeg ikke styre hvilket map der er tale om (når det er static er det selvfølgelig tvunget til at være det samme hele programmets varighed, så det er måske heller ikke ideelt). Eller skal jeg måske bruge ::domain ?
Jeg er også lidt bekymret for kompartmentalisering - jeg kunne selvfølgelig bruge
Fold kodeboks ind/udKode 

men jeg er bekymret for om det virker tungt (mit kort er 200*100 celler)?
Jeg er i det hele taget lidt optaget af performance, for mit datasæt er på 4000 arter med hver et kort bestående af 20.000 celler - dvs 80 millioner dataposter som der skal holdes styr på (det er derfor jeg bruger vector<bool>;).
Som du kan høre er problemet at jeg ikke helt har forstået OOP, og jeg synes ikke jeg kan komme videre med det ved at kigge i bøger.

Hvad angår din forslag tror jeg faktisk det er det jeg gør.
Et low-res Map over Danmark ville se sådan ud:

0001000000
0011100000
0111110110
0111000111
0011000110

og så gør jeg det tilsvarende for hver art: indlæser alle informationer i en vector<vector<bool>>, der så ligger over hinanden. index [] er så koordinatet. Eller var det ikke helt det du mente?
Venter spændt på svar, tak for I gider kigge på det :)



Indlæg senest redigeret d. 14.09.2007 12:19 af Bruger #8249
Ved hjælp af "is a" relationen kan man jo sige at du første opfattelse er forkert, da sætningen "Species is a map" ikke helt stemmer overens i mit hovede. Derimod kan man vel godt sige "Species has a map", altså "has a" relationen siger at species har en map.

"is a" relationen gælder nedarvningen.
"has a" relationen gælder for klasse variabler.

Ret mig hvis jeg tager fejl. Lang tid siden jeg har måtte forklare disse to relationer.



Ja, det kan jeg godt se - når jeg har læst om OOP beskriver de forskellen mellem inheritance og composition. I den sammenhæng er det tydeligt, som du siger, at det bør være composition (selvom jeg har tænkt 'Map has a (number of) Species' (da Map er hele danmarkskortet)). Det var det jeg mente med den lille kodestump i min sidst post.
Problemet er at jeg ikke forstår hvordan jeg får det til at fungere i praksis, når jeg har brug for at hver Species kender det Map den er en del af?



Indlæg senest redigeret d. 14.09.2007 13:35 af Bruger #8249
Jeg er helt enig med Brian. En bestemt art fugl (eller dyr i det hele taget) er ikke et kort men en art.
Og der er jo ikke noget i vejen for at et kort ved, hvilke dyr der er i et bestemt område, og at en dyrart ved, i hvilke områder af et kort, det selv lever.

Altså...et Map kan godt indeholde referencer til Species, og Species kan have en reference til et Map med koordinater eller noget i den stil.



Indlæg senest redigeret d. 17.09.2007 15:25 af Bruger #2695
OK, tak!
jeg har valgt at prøve at løse det ved at introducere en klasse til, der indeholder et Map og en vector<Species> :
Fold kodeboks ind/udKode 


Species kan så tilgå værdierne i Map'et af den vej.

Det lader til at virke :)
Men jeg får lige lyst til at spørge Robert: du skriver at Species kan have en reference til Map - er det bedre end at bruge en pointer med 'new' i dette tilfælde? Jeg har ikke helt fanget det med dynamic memory - kommer jeg til at bruge mere memory på den her måde?




Det er altid godt at bruge en pointer eller en reference. Bruger du det, skal du ikke til at lave en kopi af det du vil bruge.
Laver du en reference eller en pointer til noget data, så skal det data ikke kopieres. Du arbejder dermed med data'en gennem pointeren eller referencen.
Jeg vil sige at du bruger mere memory i dit dataSet da du laver en kopi af hver species i din vector. Du kan jo bare smide en pointer i vektoren. Men igen. Jeg er selv rimlig ny indenfor pointer området, så Robert eller en anden er nok en bedre bedømmer på det område.



Indlæg senest redigeret d. 18.09.2007 15:52 af Bruger #1151
Det er altid godt at bruge en pointer eller en reference. Bruger du det, skal du ikke til at lave en kopi af det du vil bruge.
Laver du en reference eller en pointer til noget data, så skal det data ikke kopieres. Du arbejder dermed med data'en gennem pointeren eller referencen.
Jeg vil sige at du bruger mere memory i dit dataSet da du laver en kopi af hver species i din vector. Du kan jo bare smide en pointer i vektoren. Men igen. Jeg er selv rimlig ny indenfor pointer området, så Robert eller en anden er nok en bedre bedømmer på det område.


Tak Martin,
helt klart, min intention er også at spare på hukommelsen. Jeg tror ikke jeg kan spare mere end jeg gør ved at have en vector af pointers til species, idet speciesList i eksemplet indeholder den eneste kopi af hvert Species objekt (det fremgår ikke af mit eksempel, så tak for rådet). Spørgsmålet om hvad der var mest besparende går på at når jeg passerer pointeren gør jeg det med new Map(domain), og jeg tænkte at måske optager new plads svarende til et helt nyt Map (selvom den peger på et allerede eksisterende objekt). Men jeg er ikke klar over om jeg bare kan store en reference i Species?
Eller er der en god grund til at bruge pointers?

PS jeg skal nok snart give dele points ud - jeg vil bare gerne holde tråden åben lidt endnu, for der kommer så mange interessante kommentarer :)



Tak skal I alle have, jeg har lidt mere styr på det nu. Jeg stiller pointer/reference spørgsmålet i en ny post.



t