C++: Hur använda variabler i klasser istället för globala variabler?

Permalänk

C++: Hur använda variabler i klasser istället för globala variabler?

Hej!

Jag skriver lite C++ kod i Arduino och jag behöver hjälp hur jag ska kunna lösa detta.
Här är min kod och jag ska anropa denna class->funktion->toggle som gör så att den kollar om en lysdiod är ON eller OFF. Men problemet är att den behöver veta ett värde på toggle_value först. Normalt har jag använt mig av globala variabler när jag programmerade C, men med tanke på att Arduino kör C++ (nej, Arduino kör inte C/C++ eller C. Arduino kör C++ endast då deras bibliotek är skrivna i C++) så har jag fått gått över till C++ och det känns rätt OK om man är på en grundlig nivå.

class specialFunctions { void toggle() // blink with the green LED in loops { if (toggle_value == 0) { digitalWrite(13, 1); // ON toggle_value = 1; } else { digitalWrite(13, 0); // OFF toggle_value = 0; } } float string_to_float(String data) { char carray[data.length() + 1]; // get lenght of variable data data.toCharArray(carray, sizeof(carray)); //put readStringinto an array return atof(carray); //convert the array into an Integer } }; class flik2 { // variables of pH private: int E; // E is a analog value from the pH-meter float Eo; // Eo is a constant value from the PC float k; // k is a constant value from the PC float T; // T is a constant value from the PC };

Permalänk
Hedersmedlem
Skrivet av heretic16:

Hej!

Jag skriver lite C++ kod i Arduino och jag behöver hjälp hur jag ska kunna lösa detta.
Här är min kod och jag ska anropa denna class->funktion->toggle som gör så att den kollar om en lysdiod är ON eller OFF. Men problemet är att den behöver veta ett värde på toggle_value först. Normalt har jag använt mig av globala variabler när jag programmerade C, men med tanke på att Arduino kör C++ (nej, Arduino kör inte C/C++ eller C. Arduino kör C++ endast då deras bibliotek är skrivna i C++) så har jag fått gått över till C++ och det känns rätt OK om man är på en grundlig nivå.

Om funktionen tillhör en klass kan du ju ha toggle_value som medlemsvariabel:

class specialFunctions { void toggle() // blink with the green LED in loops { if (toggle_value == 0) { digitalWrite(13, 1); // ON toggle_value = 1; } else { digitalWrite(13, 0); // OFF toggle_value = 0; } } float string_to_float(String data) { char carray[data.length() + 1]; // get lenght of variable data data.toCharArray(carray, sizeof(carray)); //put readStringinto an array return atof(carray); //convert the array into an Integer } int toggle_value = 0; };

Annars kan du göra den statisk och lokal för funktionen:

void toggle() // blink with the green LED in loops { static int toggle_value = 0; if (toggle_value == 0) { digitalWrite(13, 1); // ON toggle_value = 1; } else { digitalWrite(13, 0); // OFF toggle_value = 0; } }

Permalänk

Men vad betyder static? Varför inte int?

Borde inte static int toggle_value = 0; vara under någon private: ?

Mitt error blev

Citat:

PH-sketch_3.ino:55: error: ISO C++ forbids in-class initialization of non-const static member 'toggle_value'

Permalänk
Hedersmedlem
Skrivet av heretic16:

Men vad betyder static? Varför inte int?

Med static kommer den ihåg värdet mellan olika anrop av funktionen. Annars nollställs den varje gång.

Skrivet av heretic16:

Borde inte static int toggle_value = 0; vara under någon private: ?

Det anses nog snyggt, men just nu är allt privat (även funktionerna).

Skrivet av heretic16:

Mitt error blev

Ah, din kompilator tillåter inte att man tilldelar direkt. Du får skapa en konstruktor:

class specialFunctions { public: specialFunctions() { toggle_value = 0; } //kod här private: int toggle_value; };

Permalänk

Det blev error ändå

class specialFunctions { private: static int toggle_value = 0; void toggle() // blink with the green LED in loops { if (toggle_value == 0) { digitalWrite(13, 1); // ON toggle_value = 1; } else { digitalWrite(13, 0); // OFF toggle_value = 0; } } float string_to_float(char *data) { char carray[data.length() + 1]; //get lenght of variable data data.toCharArray(carray, sizeof(carray)); //put readStringinto an array return atof(carray); //convert the array into an Integer } };

Permalänk
Hedersmedlem

Jo, du får ha antingen

static int toggle_value = 0;

i funktionen eller en medlemsvariabel med konstruktor.

Permalänk
Skrivet av Elgot:

Jo, du får ha antingen

static int toggle_value = 0;

i funktionen eller en medlemsvariabel med konstruktor.

Vad menar du med medlemsvariabel med konstruktör?

Permalänk
Hedersmedlem
Skrivet av heretic16:

Vad menar du med medlemsvariabel med konstruktör?

Som i inlägg #4.

Permalänk
Skrivet av Elgot:

Som i inlägg #4.

Jag förstår inte logiken. Ska jag ha en funktion i public: ?

Permalänk

Det fungerar nu, men vad gör en konstruktör?
Skickar den värden till variabler?

Permalänk
Hedersmedlem
Skrivet av heretic16:

Jag förstår inte logiken. Ska jag ha en funktion i public: ?

Det är konstruktorn. Som heter likadant som klassen och dessutom saknar returtyp. Den körs varje gång man skapar en instans av klassen och kan därför användas för att till exempel initiera klassvariabler.

Permalänk
Skrivet av Elgot:

Det är konstruktorn. Som heter likadant som klassen och dessutom saknar returtyp. Den körs varje gång man skapar en instans av klassen och kan därför användas för att till exempel initiera klassvariabler.

Okej. Det kanske är smart ändå.
Jag har ett annat problem. Jag får inga error, men det hade inte jag tänkt mig heller.

Det är så att jag har deklarerat några variabler som heter E, Eo, K och T i en klass under private. Men i en annan klass är jag beroende av dessa. Hur gör jag då för att samla all värde i variabler som "globala" fast det är klasser.

Här är en bit av min kod.

http://pastebin.com/pfGS7WTQ

Permalänk
Hedersmedlem
Skrivet av heretic16:

Okej. Det kanske är smart ändå.
Jag har ett annat problem. Jag får inga error, men det hade inte jag tänkt mig heller.

Det är så att jag har deklarerat några variabler som heter E, Eo, K och T i en klass under private. Men i en annan klass är jag beroende av dessa. Hur gör jag då för att samla all värde i variabler som "globala" fast det är klasser.

Här är en bit av min kod.

http://pastebin.com/pfGS7WTQ

Om du vill komma åt dem från andra håll är det lättast att helt enkelt låta bli att lägga dem under private (eller snarare lägga dem under public). Du behöver inte heller använda static där.

Dock kan static vara bra om du vill använda klassen ugefär som du brukar använda globala variabler. Om du till exempel gör E, Eo, K och T till static-variabler kan du komma åt dem överallt genom att skriva till exempel

specialFunctions::Eo = 2;

(man behöver inte ens skapa någon klassinstans). Här vill man nog inte heller att de skall vara privata.

Permalänk

Du kan också använda dig av arv om den ena klassen är beroende av den andra.

Här har du en länk som visar ganska bra hur det fungerar.

https://www.cs.bu.edu/teaching/cpp/inheritance/intro/

Permalänk

Jag återkommer imorgon med svar! Troligtvis efter kl 15.00. Tack för all hjälp.

Permalänk

Eller skapa getters och setters för de variabler som du behöver komma åt på annat håll.

Permalänk
Skrivet av Superhepper:

Eller skapa getters och setters för de variabler som du behöver komma åt på annat håll.

Du menar att jag har en enskild klass som har hand om värden och jag kan komma åt dessa via funktioner?

Om du tar och tittar här: http://pastebin.com/27CnPT4q

Där finns det variabler som jag helst vill ha globala, men att ha globala variabler känns inte direkt rätt för mig. Det drar också mycket minne och jag har bara 32 kb att röra mig på, men jag har kommit ned till 8 Kb. Min kod är ca 6 kB.

Hur som helst så är dessa variabler som används lite här och där i olika klasser.

int E; // E is a analog value from the pH-meter static float Eo; // Eo is a constant value from the PC static float k; // k is a constant value from the PC static float T; // T is a constant value from the PC

int E är ett värde som kan ändras och det gör inget om den glöms bort. Däremot så är k, Eo och T värden som jag MÅSTE spara. Dom är konstanter, men det är när programmet har fått värden från en dator.

Permalänk
Hedersmedlem
Skrivet av heretic16:

Du menar att jag har en enskild klass som har hand om värden och jag kan komma åt dessa via funktioner?

Nja, istället för

class UU { public: int x; };

kan man ha till exempel:

class UU { public: int getX() {return x;} void setX(int i) {x = i;} private: int x; };

Permalänk
Skrivet av Elgot:

Nja, istället för

class UU { public: int x; };

kan man ha till exempel:

class UU { public: int getX() {return x;} void setX(int i) {x = i;} private: int x; };

Om man hade satt denna som public: då? Hade det varit någon skillnad då?

Permalänk
Hedersmedlem
Skrivet av heretic16:

Om man hade satt denna som public: då? Hade det varit någon skillnad då?

Nackdelen med publika variabler är att vem som helst kan pilla på dem. Om man har funktioner som ovan har man i alla fall lite mera kontroll, och man kan till exempel låta bli att skapa setX() (eller göra den privat) och därmed begränsa andra till att endast kunna läsa värdet på variabeln.

Permalänk
Skrivet av Elgot:

Nackdelen med publika variabler är att vem som helst kan pilla på dem. Om man har funktioner som ovan har man i alla fall lite mera kontroll, och man kan till exempel låta bli att skapa setX() (eller göra den privat) och därmed begränsa andra till att endast kunna läsa värdet på variabeln.

Jaha, så private är mest bara för att kunna ha kontroll. Men då vet jag.
Jag tror att jag måste lära mig lite mera C++ via Mr1Buying videos. Och troligvis skriva om mitt program när jag ser att den fungerar helt. Renskriva.