Föreläsningsanteckningar OOP-föreläsning 8, tisdag 25 september 2007 ==================================================================== Idag ==== 1. static-variabler 2. operator== 3. Repetition: Pekare till ägda och bara refererade saker 4. Glöm inte: operator=, copy-constructor 5. En vektorklass Om vi hinner: 6. En vektorklass i form av en mall (template) 7. Mer i vektorklassen 1. static-variabler =================== person-1.cpp ------------ #include using namespace std; class Person { private: string namn; int alder; int nummer; static int skapade_personer; static int existerande_personer; public: Person(string namn, int alder); ~Person(); friend ostream& operator<<(ostream& ut, Person& p); }; int Person::skapade_personer = 0; int Person::existerande_personer = 0; Person::Person(string namn, int alder) { this->namn = namn; this->alder = alder; this->nummer = ++skapade_personer; ++existerande_personer; cout << "Skapar person " << nummer << " (" << namn << ", " << alder << "). Nu finns det " << existerande_personer << " personer." << endl; } Person::~Person() { --existerande_personer; cout << "Förstör person " << nummer << " (" << namn << ", " << alder << "). Nu finns det " << existerande_personer << " personer." << endl; } ostream& operator<<(ostream& ut, Person& p) { cout << "Person " << p.nummer << " (" << p.namn << ", " << p.alder << ")" << endl; return cout; } int main() { Person p1("Göran", 57); Person p2("Fredrik", 41); Person* pp = new Person("Gudrun", 58); cout << p1 << p2 << *pp; } Körexempel ---------- Skapar person 1 (Göran, 57). Nu finns det 1 personer. Skapar person 2 (Fredrik, 41). Nu finns det 2 personer. Skapar person 3 (Gudrun, 58). Nu finns det 3 personer. Person 1 (Göran, 57) Person 2 (Fredrik, 41) Person 3 (Gudrun, 58) Förstör person 2 (Fredrik, 41). Nu finns det 2 personer. Förstör person 1 (Göran, 57). Nu finns det 1 personer. person-2.cpp ------------ #include using namespace std; class Person { private: string namn; int alder; Person* next; Person* previous; static Person* first; static Person* last; public: Person(string namn, int alder); ~Person(); friend ostream& operator<<(ostream& ut, Person& p); static int Person::antal_personer(); static void lista_personer(); }; Person* Person::first = NULL; Person* Person::last = NULL; Person::Person(string namn, int alder) { this->namn = namn; this->alder = alder; previous = last; next = NULL; if (first == NULL) first = last = this; else { last->next = this; last = this; } cout << "Skapar personen " << namn << ", " << alder << "." << endl; } Person::~Person() { if (previous == NULL) first = this->next; else previous->next = next; if (next == NULL) last = this->previous; else next->previous = previous; cout << "Förstör personen " << namn << ", " << alder << "." << endl; } ostream& operator<<(ostream& ut, Person& p) { cout << "Personen " << p.namn << ", " << p.alder << endl; return cout; } int Person::antal_personer() { Person* p = first; int antal = 0; while (p != NULL) { ++antal; p = p->next; } return antal; } void Person::lista_personer() { Person* p = first; while (p != NULL) { cout << *p; p = p->next; } } int main() { Person p1("Göran", 57); Person p2("Fredrik", 41); Person* pp = new Person("Gudrun", 58); cout << "Nu finns det " << Person::antal_personer() << " personer." << endl; cout << "Alla personer:" << endl; Person::lista_personer(); } Körexempel ---------- Skapar personen Göran, 57. Skapar personen Fredrik, 41. Skapar personen Gudrun, 58. Nu finns det 3 personer. Alla personer: Personen Göran, 57 Personen Fredrik, 41 Personen Gudrun, 58 Förstör personen Fredrik, 41. Förstör personen Göran, 57. 2. operator== ============= Användning ---------- if (p1 == p2) cout << "Lika!" << endl; else cout << "Olika!" << endl; Deklaration i klassdefinitionen ------------------------------- bool operator==(const Person& rhs); Definition ---------- bool Person::operator==(const Person& rhs) { return this->namn == rhs.namn && this->alder == rhs.alder; } En annan definition ------------------- bool Person::operator==(const Person& rhs) { return this == &rhs; } 3. Repetition: Pekare till ägda och bara refererade saker ========================================================= Fattas: operator=, copy-constructor bil-1.cpp --------- #include using namespace std; class Person { private: string namn; public: Person(string namn); }; Person::Person(string namn) { this->namn = namn; } class Motor { private: double effekt; public: Motor(double effekt); }; Motor::Motor(double effekt) { this->effekt = effekt; } class Bil { private: string bilnr; Person* owner; Motor* motor; public: Bil(string bilnr, Motor* motor, Person* owner); ~Bil(); }; Bil::Bil(string bilnr, Motor* motor, Person* owner) { this->bilnr = bilnr; this->motor = motor; this->owner = owner; } Bil::~Bil() { delete motor; } int main() { Person goran("Göran"); Person fredrik("Fredrik"); Person* gudrun_p = new Person("Gudrun"); Motor* m1_p = new Motor(110.0); Motor* m2_p = new Motor(120.0); Bil b1("RFN 540", m1_p, &goran); Bil* bp = new Bil("BOS 118", m2_p, gudrun_p); delete gudrun_p; delete bp; } 4. Glöm inte: operator=, copy-constructor ========================================= Problem kvar ------------ b1 = *bp; En lösning: privat operator= ---------------------------- class Bil { private: Person* owner; Motor* motor; const Bil& operator=(const Bil& b); public: Bil(string bilnr, Motor* motor, Person* owner); ~Bil(); }; 5. En vektorklass ================= vektor-1.cpp ------------ #include using namespace std; class Vektor { private: double* lagring; int storlek; public: Vektor(int storlek); Vektor(const Vektor& original); ~Vektor(); const Vektor& operator=(const Vektor& original); }; Vektor::Vektor(int storlek) { this->storlek = storlek; lagring = new double[storlek]; } Vektor::Vektor(const Vektor& original) { this->storlek = original.storlek; lagring = new double[original.storlek]; for (int i = 0; i < storlek; ++i) lagring[i] = original.lagring[i]; } Vektor::~Vektor() { delete [] lagring; } const Vektor& Vektor::operator=(const Vektor& original) { if (this != &original) { delete [] lagring; this->storlek = original.storlek; lagring = new double[original.storlek]; for (int i = 0; i < storlek; ++i) lagring[i] = original.lagring[i]; } return *this; } int main() { Vektor v1(3); Vektor v2 = 7; Vektor v3 = v1; v2 = v1; } 6. En vektorklass i form av en mall (template) ============================================== vektor-2.cpp ------------ #include using namespace std; template class Vektor { private: T* lagring; int storlek; public: Vektor(int storlek); Vektor(const Vektor& original); ~Vektor(); const Vektor& operator=(const Vektor& original); }; template Vektor::Vektor(int storlek) { this->storlek = storlek; lagring = new T[storlek]; } template Vektor::Vektor(const Vektor& original) { this->storlek = original.storlek; lagring = new T[original.storlek]; for (int i = 0; i < storlek; ++i) lagring[i] = original.lagring[i]; } template Vektor::~Vektor() { delete [] lagring; } template const Vektor& Vektor::operator=(const Vektor& original) { if (this != &original) { delete [] lagring; this->storlek = original.storlek; lagring = new T[original.storlek]; for (int i = 0; i < storlek; ++i) lagring[i] = original.lagring[i]; } return *this; } int main() { Vektor v1(3); Vektor v2 = 7; Vektor v3 = v1; v2 = v1; Vektor v4(10); } 7. Mer i vektorklassen ====================== Användning ---------- Vektor v(3); v[0] = 7.1; v[2] = 5.9; cout << "v[0] == " << v[0] << endl; cout << "v[1] == " << v[1] << endl; Deklaration i klassdefinitionen ------------------------------- T& Vektor::operator[](int i); Definition ---------- template T& Vektor::operator[](int i) { return lagring[i]; }