Hjälp mig loss ur C-träsket, tack

Permalänk
Medlem

Hjälp mig loss ur C-träsket, tack

Lär mig C++, å är rätt färsk. Har kört fast, skulle behöva hjälp att komma loss.

Handlar om klasser, s.k. "public accessor methods", som används för att tillfälligt manipulera data inuti privata klasser. Grejen är alltså att klassen ska vara "Private" men att man ändå ska kunna manipulera vissa data utifrån. Får f-n inte ihop hur det funkar utifrån nedanstående exempel. Får känslan av att instruktionerna är felaktiga.

Klassen ser ut såhär:

1 class Katt 2 { 3 public: 4 5 unsigned int Hamta_Alder(); 6 void Satt_Alder(unsigned int Alder); 7 8 unsigned int Hamta_Vikt(); 9 void Satt_Vikt(unsigned int Vikt); 10 11 void Mjau(); 12 13 private: 14 unsigned int dessAlder; 15 unsigned int dessVikt; 16 }; 17 18 void main () 19 { 20 Katt Misse; 21 Misse.Satt_Alder(5); 22 }

Enligt läroplanen ska man kunna införa kattfans ålder i klassens "dessAlder"-variabel, genom att först initiera en Katt (Katt Misse;) och sen infoga åldern (5 år) i den privata delen av katt-klassen, genom kommandot Misse.Satt_Alder(5);

Men ... compilern idiot-förklarar mig varje gång, tvärstoppar, å spottar ur sig en massa bullshit, typ "public: void __thiscall Katt::Satt_Alder(unsigned int)" (?Satt_Alder@Katt@@QAEXI@Z) referenced in function _main" etc

Om jag förstår ovanstående här rätt, så .. hänvisar ju inte funktionen Satt_Alder till variabeln "dessAlder". Satt_Alder-funktionen kommer istället att ange värdet "5" till alla osignerade integer-variabler den hittar inom klassen (?)

Visa signatur

Jag använder datorn för att göra jobb bättre, inte för att jobba med att göra datorn bättre

Permalänk
Medlem

Hej !
Problemet är att du bara skrivit deklarationerna för dina medlemsfunktioner i klassen, dvs du har bara skrivit "mallarna" för hur de ska se ut utåt.
De kan inte fungera förrän du också skrivit själva koden till dem, så du har helt rätt i att dessAlder inte har någon koppling till dinSatt_Alder funktion.

Antingen skriver du koden direkt under alla funtioner som tex
void Satt_Alder(unsigned int Alder)
{
dessAlder = Alder;
}

eller så gör du det separat utanför classbeskrivningen som

void katt::Satt_Alder(unsigned int Alder)
{
dessAlder = Alder;
}

Vanligen brukar man lägga klassernas deklarationer (dvs det som ser ut som du skrivit) i en separat "header" fil som bör ha ändelsen .h
Sedan skriver man själva koden till medlemsfunktionerna i en .cpp fil som importerar denna headerfil (görs med kommandot #import "katt.h" överst om det är vad din headerfil heter.)

Sedan har det kanske inte direkt med din fråga att göra, men du säger att din klass ska vara private.
Att vara private är ingen egenskap du kan tilldela en fristående klass (när du läser vidare kommer du dock att stöta på att du kan göra en klass "private" för en annan klass i samband med arv av klasser).

Däremot är vissa delar av din klass private utåt och det är de delar som du skriver efter "private :"
Värt att notera är att allt i din klass är private som default. Glömmer du att skriva "public :" eller "protected :" så är alltså allt private. Detta är lätt att göra fel på som nybörjare.
Gör du däremot en sk "struct" istället för "class" så är det tvärtom, allt är public från början. Detta är det enda som skiljer en "struct" från en "class".

Visa signatur

Namn : Jesper | Ålder : 45 | In-game namn : iller
Yrke : Matematisk modellerare (finansiell matematik), mjukvaruutvecklare för risksystem.
Utbildning : Doktor i matematik + en del mat-stat, numme och IT-relaterat.

Permalänk
Medlem

Dom funktionsanropen i klassen, var alltså inga hårdkodade kommandon eller funktioner med specifik karaktär under just paraplyet "klass", vilket man lätt får intryck av att dom ska vara - iaf när man använder det läromaterial jag gör.

Klassen ovan, inklusive uppgiften med den, är helt och hållet författad (och beskriven) av litteraturen. Medlems-funktionerna Satt_Alder m.fl. är ofullständiga, men detta betraktas som komplett och följs inte upp vidare. Ytterligare en "blind spot" i läromaterialet alltså. Tufft värre, när materialet är bra 95% av tiden, och rätt vad det är kommer såna här svarta hål, där man inte ens vet att man missar grejor liksom. Grundkurs, med överkurs insmyget.

Får tacka så mycket för hjälpen, Jesper. Bra beskrivet. Ser precis hur jag ska förstå och hantera det nu.

... men jag har svårt att se nödvändigheten att använda detta i liten skala? Det verkar sjukt omständigt att skriva mellansteg och omportningar till varenda funktion. Och varför bara göra det i klasser, varför inte göra det för varenda funktion som finns i hela programmet? Vilket resulterar i att programmet utgörs till hälften av mellanhand-funktioner ... sjukt ...

Visa signatur

Jag använder datorn för att göra jobb bättre, inte för att jobba med att göra datorn bättre

Permalänk
Medlem

Tjo!

Anledningen med accessmetoder brukar vara att de ska agera som en kontroll för att man inte sätter felaktiga värden i en variabel. Vad som är felaktigt eller inte är så klart upp till dig. I dessa fall så skulle både ålder och vikt kännas felaktiga om de var negativa till exempel (har du någonsin sett en katt som väger -10 kg?). Genom att ha en accessormetod för att sätta värdet på visa variablar så har man möjligheten att alltid se till att ålder (som exempel) alltid har ett korrekt värde då det är enda sättet att ändra den interna variabeln.

I verkligheten och i liten skala som du beskriver det så är oftast accessormetoderna så dumma som beskrivs ovanför (man bara sätter respektive hämtar variabeln) men genom att man har förberett för att kontroll så blir det lättare att genomföra när man väl känner behov för det.

//C

Permalänk
Medlem
Skrivet av TomKe:

... men jag har svårt att se nödvändigheten att använda detta i liten skala? Det verkar sjukt omständigt att skriva mellansteg och omportningar till varenda funktion. Och varför bara göra det i klasser, varför inte göra det för varenda funktion som finns i hela programmet? Vilket resulterar i att programmet utgörs till hälften av mellanhand-funktioner ... sjukt ...

Jo, jag kände likadant när jag först började läsa C++. Något av det svåraste att förstå som nybörjare är (i allfall var det så för mig) vad som var nödvändigt att skriva för att allt skulle fungera och varför.

Och som sagt, så är det ju inte heller så superviktigt när det gäller små klasser och program att separera de där "mellanstegen" från själva koden till funktionerna.
Gör man däremot ett större projekt med klasser med många medlemsfunktioner så blir det svårt att få en överblick över vilka funktioner som finns att tillgå om de skrivs tillsammmans med all kod på många sidor.
Man kan se "mellanstegen" som ett interface för någon som ska använda klassen. Den som ska använda klassen vill snabbt se vad som finns, utan att kanske vilja bry sig om hur funktionerna fungerar "bakom skalet". Det är lite som på en mobiltelefon, dator, bil eller vad man nu kan tänka sig. Användaren vill veta hur prylarna används, men kanske inte hur de fungerar inuti.

Det där tankesättet underlättar enormt när man skriver större projekt och klasser behöver använda andra klasser. När man skriver koden till sådana projekt skulle det bli väldigt svårt om man hela tiden var tvungen att rota igenom en massa kod.

Men som sagt, för små program kan det ju kännas lite meningslös. Jag antar att poängen är att man ska lära sig att strukturera programmen på det sättet så att man sedan kan fortsätta med det i större program när det hela blir mer relevant.

Visa signatur

Namn : Jesper | Ålder : 45 | In-game namn : iller
Yrke : Matematisk modellerare (finansiell matematik), mjukvaruutvecklare för risksystem.
Utbildning : Doktor i matematik + en del mat-stat, numme och IT-relaterat.

Permalänk
Medlem

Ovanstående poänger verkar alltmer relevanta. Har gått vidare i kodboken sen jag skrev tråden, och börjat ana hur det är tänkt att hänga ihop - precis som ni beskriver här ovan.

Antar att det är lätt att känna sig irriterad och bli lite anti, när läromaterialet tabbar sig så man själv måste söka efter svar som man inte ens kan identifiera som svar ännu. Man är liksom i det där läget att ... man har lagt ner tillräckligt mycket tid på just detta material så att det inte blir värt att släppa detta och börja om från noll med ett annat material. Man har ju ingen garanti för att den läroboken skulle vara bättre heller

Vägen till sanningen är nog aldrig rak. Men man tackar för hjälpen ibland svängarna

Visa signatur

Jag använder datorn för att göra jobb bättre, inte för att jobba med att göra datorn bättre

Permalänk
Skrivet av TomKe:

... men jag har svårt att se nödvändigheten att använda detta i liten skala? Det verkar sjukt omständigt att skriva mellansteg och omportningar till varenda funktion. Och varför bara göra det i klasser, varför inte göra det för varenda funktion som finns i hela programmet? Vilket resulterar i att programmet utgörs till hälften av mellanhand-funktioner ... sjukt ...

Jag håller med dig om att det är väldigt osmidigt, och det är egentligen inga språk som har kommit efter C och C++ (och Objective-C och kanske nått mer?) som kräver det längre.

Anledningen till att det blev så en gång i tiden var för att datorerna hade så lite minne så de som konstruerade språket bestämde att kompilatorn behöver kunna kompilera en cpp-fil i taget helt fristående, och därför blir man tvungen att manuellt separera ut deklarationer för innehållet i andra cpp-filer till header-filer.

Nu när datorer har gott om minne och processorkraft så finns det ingen poäng att göra så längre, och nyare språk kräver det inte heller. Det kan vara bra att tänka på ibland när man ser nått som känns lite ologiskt att det kan ha funnits anledningar till val som gjordes för länge sen som inte "makes sense" längre.

Permalänk
Medlem
Skrivet av VirtualIntent:

Jag håller med dig om att det är väldigt osmidigt, och det är egentligen inga språk som har kommit efter C och C++ (och Objective-C och kanske nått mer?) som kräver det längre.

Anledningen till att det blev så en gång i tiden var för att datorerna hade så lite minne så de som konstruerade språket bestämde att kompilatorn behöver kunna kompilera en cpp-fil i taget helt fristående, och därför blir man tvungen att manuellt separera ut deklarationer för innehållet i andra cpp-filer till header-filer.

Nu när datorer har gott om minne och processorkraft så finns det ingen poäng att göra så längre, och nyare språk kräver det inte heller. Det kan vara bra att tänka på ibland när man ser nått som känns lite ologiskt att det kan ha funnits anledningar till val som gjordes för länge sen som inte "makes sense" längre.

Men C++ kräver inte att man separerar deklarationerna från definitionerna. Det går alldeles utmärkt att skriva dem på samma plats.
Däremot blir det mycket mer överskådligt om man separerar dem.

Visa signatur

Namn : Jesper | Ålder : 45 | In-game namn : iller
Yrke : Matematisk modellerare (finansiell matematik), mjukvaruutvecklare för risksystem.
Utbildning : Doktor i matematik + en del mat-stat, numme och IT-relaterat.

Permalänk
Skrivet av JesperT:

Men C++ kräver inte att man separerar deklarationerna från definitionerna. Det går alldeles utmärkt att skriva dem på samma plats.
Däremot blir det mycket mer överskådligt om man separerar dem.

Men om du har beroenden mellan innehållet i olika cpp-filer (vilket jag gissar är regel snarare än undantag om de hör till samma program), hur ska kompilatorn medan den kompilerar den ena cpp-filen få kännedom om innehållet i den andra cpp-filen som den vill använda sig av? Du kan antagligen skriva in deklarationerna flera gånger i olika filer men jag antar att det inte är så du menar? Eller du kanske tänker att om man skriver ett program som bara är en cpp-fil så behöver man inte separera någonting?

Permalänk
Medlem
Skrivet av VirtualIntent:

Eller du kanske tänker att om man skriver ett program som bara är en cpp-fil så behöver man inte separera någonting?

Ja, det var det jag menade, så vi tänkte nog på lite olika saker.

Visa signatur

Namn : Jesper | Ålder : 45 | In-game namn : iller
Yrke : Matematisk modellerare (finansiell matematik), mjukvaruutvecklare för risksystem.
Utbildning : Doktor i matematik + en del mat-stat, numme och IT-relaterat.

Permalänk
Medlem
Skrivet av VirtualIntent:

Men om du har beroenden mellan innehållet i olika cpp-filer (vilket jag gissar är regel snarare än undantag om de hör till samma program), hur ska kompilatorn medan den kompilerar den ena cpp-filen få kännedom om innehållet i den andra cpp-filen som den vill använda sig av? Du kan antagligen skriva in deklarationerna flera gånger i olika filer men jag antar att det inte är så du menar? Eller du kanske tänker att om man skriver ett program som bara är en cpp-fil så behöver man inte separera någonting?

Beroenden mellan olika .cpp-filer löser man oftast genom att använda sig av .h-filerna som gränssnitt. Dvs om p1.cpp använder klasser från p2.cpp, så deklareras klasserna i p2.h som sedan inkluderas i p1.cpp.

Kompilatorn behöver inte veta om innehållet i p2.cpp när den kompilerar p1.cpp, varje .cpp-fil kompileras normalt sett individuellt till en objektfil. Det är sedan i länkningssteget som allting sys ihop till en komplett exekverbar binärfil.