Lycantrophe Skrevet 3. mai 2011 Del Skrevet 3. mai 2011 (endret) Ikke for arrays (som du allokerer et gitt antall plasser til uansett), men for vector og lignende er det det. Endret 3. mai 2011 av Lycantrophe Lenke til kommentar
Joachricar Skrevet 3. mai 2011 Del Skrevet 3. mai 2011 Dette skal vel funke ? int lengdeAvTab = sizeof(tabellen) / sizeof(tabelltypen f.eks int) Lenke til kommentar
GeirGrusom Skrevet 4. mai 2011 Del Skrevet 4. mai 2011 Dette skal vel funke ? int lengdeAvTab = sizeof(tabellen) / sizeof(tabelltypen f.eks int) Jepp. Dette er vel egentlig en litt rar oppførsel i C? #define ARRAY_COUNT(ARRAY) (sizeof(ARRAY) / sizeof(ARRAY[0]) Lenke til kommentar
TheMaister Skrevet 4. mai 2011 Del Skrevet 4. mai 2011 Nei, gir mening med f.eks memcpy eller memset. memset(arr, 0, sizeof(arr)); sizeof() ber jo tross alt om størrelse, ikke antall. Lenke til kommentar
GeirGrusom Skrevet 4. mai 2011 Del Skrevet 4. mai 2011 Jojo. Men arr er også synonymt med en peker? Lenke til kommentar
haarod Skrevet 4. mai 2011 Del Skrevet 4. mai 2011 Jeg har skrevet en funksjon som skal redusere en brøk ved å finne høyeste felles divisor. Problemet er at programmet avbrytes av en "floating point exception". Her er koden: int Fraction::reduce(int& num, int& den){ int b = den; int a = num; int temp; if (a > b){ temp = a; a = b; b = temp; //b (bigger) er størst } temp = 1; while (temp != 0){ cout << "TEMP: " << temp << endl; temp = b%a; if (temp != 0){ b = a; a = temp; //cout << "Breaking off loop.." << endl; //break; } } int gcd = temp; num = (num/gcd); den = (den/gcd); cout << "GCD: " << gcd << ", NUM: " << num << ", DEN: " << den << endl; return num, den; } Jeg har prøvd å skrive ut noen variabler i bånn av funksjonen, men den avbryter før det. Lenke til kommentar
Lycantrophe Skrevet 4. mai 2011 Del Skrevet 4. mai 2011 (endret) Jeg gjorde det til en øving en gang, da så det slik ut: for GCD: long a = this->numerator; long b = this->denominator; long t; while(b != 0){ t = b; b = a%b; a = t; } return a; For forenklingen: int g = gcd(); this->numerator = this->numerator/g; this->denominator = this->denominator/g; Ser ikke floating point exception helt umiddelbart, men det så noe enklere ut. Du trenger heller ikke sjekke om a eller b er størst ettersom euclid's algorithm korrigerer dette ved første kjøring uansett. Endret 4. mai 2011 av Lycantrophe Lenke til kommentar
haarod Skrevet 4. mai 2011 Del Skrevet 4. mai 2011 OK, takk for hjelpen. Jeg har ikke helt kontroll på this-operatoren, men jeg skal sjekke det ut. Lenke til kommentar
Lycantrophe Skrevet 4. mai 2011 Del Skrevet 4. mai 2011 Kan i grunn se bort ifra den, det var mest for å lære meg det selv. this brukes når du må eksplisitt vise til at det er medlemsvariabelen i den aktuelle klassen. Nytten kommer når du har to variabler med samme navn der den ene har scope i metoden, den andre i klassen. Lenke til kommentar
TheMaister Skrevet 8. mai 2011 Del Skrevet 8. mai 2011 Jojo. Men arr er også synonymt med en peker? Array og peker er to helt forskjellige ting. For eksempel her når det er spørsmål om størrelse. I bruk har array veldig lett for å "decaye" til en peker, dog. Lenke til kommentar
haarod Skrevet 12. mai 2011 Del Skrevet 12. mai 2011 Hei. Jeg støtte på noe som jeg synes er litt rart. Jeg har drevet med litt overlagringer av ++ og -- operatorene, både som medlem av, friend av og utenfor klassen PrimeNumber. Koden over er overlagringene som er utenfor klassen, men både med friend og disse utenfor så er deklareringene mine forskjellige fra definisjonene. Det fungerer likevel som det skal. Er det noen som kan forklare meg hvorfor dette fungerer? Jeg har heller ikke helt skjønt syntaksen til deklareringene med alle "constene". Og når lønner det seg å bruke friend, medlem eller utenfor når det er snakk om overlagringer? Her er litt av koden. class PrimeNumber{ public: PrimeNumber(): number(1){}; PrimeNumber(int newNumber); /*PrimeNumber operator ++(); //Prefix, call-by-reference PrimeNumber operator ++(int); //Postfix med int-markør, call-by-value PrimeNumber operator --(); PrimeNumber operator --(int);*/ void setNumber(int newNumber); int getNumber(); void findNext(); //int eller void? void findLast(); void output(); /*friend const PrimeNumber operator ++(const PrimeNumber& p1); friend const PrimeNumber operator ++(const PrimeNumber& p1, int); friend const PrimeNumber operator --(const PrimeNumber& p1); friend const PrimeNumber operator --(const PrimeNumber& p1, int);*/ private: bool testNumber(); int number; }; const PrimeNumber operator ++(const PrimeNumber& p1); const PrimeNumber operator ++(const PrimeNumber& p1, int); const PrimeNumber operator --(const PrimeNumber& p1); const PrimeNumber operator --(const PrimeNumber& p1, int); const PrimeNumber operator ++(PrimeNumber& p1){ p1.findNext(); return p1; } const PrimeNumber operator ++(PrimeNumber& p1, int){ PrimeNumber temp = p1; p1.findNext(); return temp; } const PrimeNumber operator --(PrimeNumber& p1){ p1.findLast(); return p1; } const PrimeNumber operator --(PrimeNumber& p1, int){ PrimeNumber temp = p1; p1.findLast(); return temp; } Lenke til kommentar
TheMaister Skrevet 12. mai 2011 Del Skrevet 12. mai 2011 Det er vel ikke mulig å overlagre på den måten? ++ og -- arbeider vel bare på enkelt-variabler? Lenke til kommentar
haarod Skrevet 12. mai 2011 Del Skrevet 12. mai 2011 Det stemmer, men det er jo det jeg har gjort? I medlemsoverlagringene har jeg ingen argumenter, men på overlagringen utenfor må jeg jo ha et argument da den ikke har tilgang til klassen i seg selv. Jeg får også feilmelding når jeg prøver og kompilere med friend-overlagringene hvis jeg ikke har input, selv om den egentlig skal ha tilgang til de private variablene? Lenke til kommentar
haarod Skrevet 12. mai 2011 Del Skrevet 12. mai 2011 (endret) Jeg legger ved resten koden. #include <iostream> #include <cstdlib> #include <cmath> using namespace std; class PrimeNumber{ public: PrimeNumber(): number(1){}; PrimeNumber(int newNumber); /*PrimeNumber operator ++(); //Prefix, call-by-reference PrimeNumber operator ++(int); //Postfix med int-markør, call-by-value PrimeNumber operator --(); PrimeNumber operator --(int);*/ void setNumber(int newNumber); int getNumber(); void findNext(); //int eller void? void findLast(); void output(); friend const PrimeNumber operator ++(/*const PrimeNumber& p1*/); //Prøvde uten argumenter, men det fungerer ikke friend const PrimeNumber operator ++(const PrimeNumber& p1, int); friend const PrimeNumber operator --(const PrimeNumber& p1); friend const PrimeNumber operator --(const PrimeNumber& p1, int); private: bool testNumber(); int number; }; /*const PrimeNumber operator ++(PrimeNumber& p1); const PrimeNumber operator ++(PrimeNumber& p1, int); const PrimeNumber operator --(PrimeNumber& p1); const PrimeNumber operator --(PrimeNumber& p1, int); const PrimeNumber operator ++(PrimeNumber& p1){ p1.findNext(); return p1; } const PrimeNumber operator ++(PrimeNumber& p1, int){ PrimeNumber temp = p1; p1.findNext(); return temp; } const PrimeNumber operator --(PrimeNumber& p1){ p1.findLast(); return p1; } const PrimeNumber operator --(PrimeNumber& p1, int){ PrimeNumber temp = p1; p1.findLast(); return temp; }*/ const PrimeNumber operator ++(){ number.findNext(); return p1; } const PrimeNumber operator ++(PrimeNumber& p1, int){ PrimeNumber temp = p1; p1.findNext(); return temp; } const PrimeNumber operator --(PrimeNumber& p1){ p1.findLast(); return p1; } const PrimeNumber operator --(PrimeNumber& p1, int){ PrimeNumber temp = p1; p1.findLast(); return temp; } /*PrimeNumber PrimeNumber::operator ++(){ findNext(); return number; } PrimeNumber PrimeNumber::operator ++(int){ int temp = number; findNext(); return temp; } PrimeNumber PrimeNumber::operator --(){ findLast(); return number; } PrimeNumber PrimeNumber::operator --(int){ int temp = number; findLast(); return temp; }*/ PrimeNumber::PrimeNumber(int newNumber){ number = newNumber; if (!testNumber()){ //Hvordan gjøre dette mer elegant? cout << "Not a prime number.. Shutting down.." << endl; exit(1); } } int main(){ PrimeNumber p1(11); p1++; p1.output(); for (int i=0; i<50; i++){ ++p1; } p1.output(); p1--; p1.output(); --p1; p1.output(); return 0; } void PrimeNumber::output(){ cout << number << endl; } int PrimeNumber::getNumber(){ return number; } void PrimeNumber::setNumber(int newNumber){ number = newNumber; if (!testNumber()){ cout << "Not a prime number. Shutting down.." << endl; exit(1); } } bool PrimeNumber::testNumber(){ int j=0; for (int i=2; i<=sqrt(number); i++){ if (number%i == 0){ j++; if (j>0){ return false; } //return true; Problemet her er at 16 vil bli returnert som et primtall fordi 16%3 != 0, //og funksjonen returnerer da true ved første tilfellet. } } return true; } void PrimeNumber::findNext(){ do{ number++; }while (!testNumber()); //return number; } void PrimeNumber::findLast(){ do{ number--; }while (!testNumber()); //return number; } Endret 12. mai 2011 av haarod Lenke til kommentar
haarod Skrevet 13. mai 2011 Del Skrevet 13. mai 2011 (endret) Her kommer jeg med et problem til. Jeg har lagd en klasse ved navn Student som inneholder et navn (string), antall fag studenten tar (int) og et dynamisk array som inneholder navnet på fagene. Problemet er at jeg ikke kan inpute mer enn fire fag før jeg får segmentation fault (som betyr at det ikke er mer minne?). Jeg legger ved hele koden, men uthever problemområdene. #include <cstdlib> #include <iostream> #include <string> using namespace std; class Student{ public: Student(); Student(string newName, int newNumClasses); Student(const Student& newStudent); Student& operator =(const Student& rightSide); int getNumClasses() {return numClasses;} void setNumClasses(int newNumClasses); string getName() {return name;} void setName(string newName); [b]void input();[/b] void newLine(); void output(); ~Student(); private: string name; int numClasses; [b]string *classList;[/b] }; int main(){ Student Haakon; [b]Haakon.input();[/b] //Kun hvis jeg setter numClasses større enn 4. Haakon.output(); return 0; } Student::Student(): name("Ingen T. Ing"), numClasses(4){ classList = new string[numClasses]; } Student::Student(string newName, int newNumClasses): name(newName){ if (newNumClasses >=0){ numClasses = newNumClasses; } classList = new string[numClasses]; } Student::Student(const Student& newStudent): name(newStudent.name), numClasses(newStudent.numClasses){ classList = new string[numClasses]; for (int i=0; i<numClasses; i++){ classList[i] = newStudent.classList[i]; } } [b]void Student::input(){ cout << "Skriv inn navnet ditt: "; getline(cin, name); //newLine(); //Overflødig her cout << "Du skrev: " << name << endl; cout << "\nSkriv inn antall klasser (minst 0): "; cin >> numClasses; cout << "Du skrev: " << numClasses << endl; newLine(); if (numClasses < 0){ cout << "Antall klasser kan ikke være negativt. Avslutter.." << endl; exit(1); } string className; for (int i=0; i<numClasses; i++){ cout << "Skriv inn fag:\n"; getline(cin, className); //prøv med cin >> className etterpå. /*if (classList == NULL){ cout << "Out of memory. Shutting down.." << endl; exit(1); }*/ //Prøvde og kjøre denne testen, men jeg er ikke helt sikker på syntaks, men jeg skal jobbe mer med den. classList[i] = className; } }[/b] void Student::newLine(){ string avfall; getline(cin, avfall); } void Student::output(){ cout << name << " sine fag: "; for (int i=0; i<numClasses; i++){ cout << classList[i]; if (i<numClasses-1){ cout << ", "; } } cout << endl; } Student& Student::operator =(const Student& rightSide){ if (numClasses != rightSide.numClasses){ delete [] classList; classList = new string[rightSide.numClasses]; } numClasses = rightSide.numClasses; name = rightSide.name; for (int i=0; i<numClasses; i++){ classList[i] = rightSide.classList[i]; } return *this; //Adressen til det kallende objektet. } [b]Student::~Student(){ delete [] classList; }[/b] void Student::setNumClasses(int newNumClasses){ if (newNumClasses >= 0){ numClasses = newNumClasses; } else{ cout << "Number of classes can't be negative. Shutting down.." << endl; exit(1); } } void Student::setName(string newName){ name = newName; } Det gikk visst ikke an å ha fet skrift inne i kodeboksen, men problemet ligger i input(), og muligens i destructoren ~Student(). EDIT: Jeg fant problemet. Jeg hadde satt default constructoren til å sette av plsas til fire fag, men endret det nå til 50 så da fungerer det fint. Endret 13. mai 2011 av haarod Lenke til kommentar
Joachricar Skrevet 13. mai 2011 Del Skrevet 13. mai 2011 Det som skjer er at den prøver å legge til en verdi utenfor arrayet, ikke at det er tomt for minne. Ikke skyt meg om jeg tar feil, men om du setter arrayet til 50, da bruker programmet alle 50 plassene, og bruker mao unødvendig mye minne. Ta heller å se på vector-klassen: http://www.cplusplus.com/reference/stl/vector/ Lenke til kommentar
haarod Skrevet 13. mai 2011 Del Skrevet 13. mai 2011 Det er en mulighet ja, men jeg prøver og bruke litt pekere og dynamiske arrays så derfor bruker jeg den. Men takk for tipset. Lenke til kommentar
zotbar1234 Skrevet 13. mai 2011 Del Skrevet 13. mai 2011 (endret) Jeg har drevet med litt overlagringer av ++ og -- operatorene, både som medlem av, friend av og utenfor klassen PrimeNumber. ("overlagring"? *grøsss*) La oss se: "A unary operator (...) can be defined by either a nonstatic member function taking no arguments or a nonmember function taking one argument." Noen operatorer er det veldig naturlig å ha utenfor klassen (eksempelvis op+()) for å unngå asymmetrisk oppførsel; mens andre er det kanskje ikke urimelig å definere som medlemmer. Koden over er overlagringene som er utenfor klassen, men både med friend og disse utenfor så er deklareringene mine forskjellige fra definisjonene. Det fungerer likevel som det skal. Er det noen som kan forklare meg hvorfor dette fungerer? Det fungerer ikke som "det skal", for en rimelig definisjon av skal Men da må man lage et par eksempler. En veldig grei regel (og spesielt for en klasse som skal opptre som et tall) er å følge semantikken til de innebygde operatorne. Jeg har heller ikke helt skjønt syntaksen til deklareringene med alle "constene". Og når lønner det seg å bruke friend, medlem eller utenfor når det er snakk om overlagringer? Det finnes ingen allmennanvendelig oppskrift, selv om Scott Meyers skriver noe om akkurat dette i "Effective C++". Det kan se ut som at det er litt forvirring på gang: "friend"-deklarasjoner er egentlig ikke en del av avgjørelsen om hvorvidt en funksjon skal være medlem eller ej. Men en kort huskeliste: * Funksjoner som kan tenkes å kunne være virtuelle, må nødvendigvis være medlemmer. * Noen funksjoner kan ikke være medlemmer, grunnet deres virkemåte (f.eks. op<< og op>> på streams, kommutative binære aritmetiske operatorer, osv.) * Det spørs opplagt i hvilken grad operatoren trenger tilgang til implementasjonsdetaljene i klassen for å avgjøre om de skal være medlemmer eller ej. class PrimeNumber{ public: PrimeNumber(): number(1){}; PrimeNumber(int newNumber); PrimeNumber operator ++(); //Prefix, call-by-reference PrimeNumber operator ++(int); //Postfix med int-markør, call-by-value PrimeNumber operator --(); PrimeNumber operator --(int); Nei. En av hovedreglene (ikke bare ved operator-overloading, men ellers også) er "principle of least surprise". Egne operatorer må av den grunn matche semantikken til måten sammenlignbare innebygde operatorer fungerer. Prefiksoperatorne returnerer en PrimeNumber&. Postfiksoperatorne returnerer en kopi, og derfor en const PrimeNumber&. (forresten, hva betyr "prefix, call-by-reference" her?) const PrimeNumber operator ++(PrimeNumber& p1){ p1.findNext(); return p1; } Dette kan bli en ekkel overraskelse, når du sender resultatet av preinkrement til en funksjon som modifiserer objektet. Returner en referanse til det objektet du modifiserer. Endret 13. mai 2011 av zotbar1234 Lenke til kommentar
zotbar1234 Skrevet 13. mai 2011 Del Skrevet 13. mai 2011 Det er en mulighet ja, men jeg prøver og bruke litt pekere og dynamiske arrays så derfor bruker jeg den. Men da skriver du din egen vector og bruker den. Ingen grunn til å fjase med utilslørte arrays i C++ i en klasse som har en helt annen oppgave. Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå