Om man vill vara mer avancerad av sig fungerar det här också bra för lika:class Datum { private: int ar; int manad; int dag; public: Datum(int ar, int manad, int dag); void skriv(); void las(); bool lika(Datum rhs); };
bool lika(const Datum& rhs);
Ett alternativt sätt att skriva konstruktorn:Datum::Datum(int ar, int manad, int dag) { this->ar = ar; this->manad = manad; this->dag = dag; } void Datum::skriv() { cout << ar << "-" << manad << "-" << dag; } void Datum::las() { char c; cin >> ar >> c >> manad >> c >> dag; } bool Datum::lika(Datum rhs) { return ar == rhs.ar && manad == rhs.manad && dag == rhs.dag; }
Datum::Datum(int ar, int manad, int dag) : ar(ar), manad(manad), dag(dag) { }
int main() { Datum d1(1963, 12, 11); Datum d2(1963, 12, 11); cout << "Skriv två datum:" << endl; d1.las(); d2.las(); cout << "Datumen: "; d1.skriv(); cout << " "; d2.skriv(); cout << endl; if (d1.lika(d2)) cout << "Lika!" << endl; else cout << "Olika!" << endl; return 0; }
ostream& operator<< (ostream& out, const Datum& datum) { out << datum.ar << "-" << datum.manad << "-" << datum.dag; return out; } istream& operator>> (istream& in, Datum& datum) { char c; in >> datum.ar >> c >> datum.manad >> c >> datum.dag; return in; } bool Datum::operator== (Datum& andra_datumet) { return ar == andra_datumet.ar && manad == andra_datumet.manad && dag == andra_datumet.dag; }
int main() { Datum d1(1963, 12, 11); Datum d2(1963, 12, 11); cout << "Skriv två datum:" << endl; cin >> d1 >> d2; cout << "Datumen: " << d1 << " " << d2 << endl; if (d1 == d2) cout << "Lika!" << endl; else cout << "Olika!" << endl; return 0; }
int main () { Datum* d1p = new Datum(1963, 12, 11); Datum* d2p = new Datum(1963, 12, 11); cout << "Skriv två datum:" << endl; d1p->las(); d2p->las(); cout << "Datumen: "; d1p->skriv(); cout << " "; d2p->skriv(); cout << endl; if (d1p->lika(*d2p)) cout << "Lika!" << endl; else cout << "Olika!" << endl; delete d1p; delete d2p; return 0; }
En alternativ lösning:
int main () { Datum* d1p = new Datum(1963, 12, 11); Datum* d2p = new Datum(1963, 12, 11); cout << "Skriv två datum:" << endl; cin >> *d1p >> *d2p; cout << "Datumen: " << *d1p << " " << *d2p << endl; if (*d1p == *d2p) cout << "Lika!" << endl; else cout << "Olika!" << endl; delete d1p; delete d2p; return 0; }
En alternativ lösning, där inmatningen avslutas genom att man matar in datumet 0-0-0:#include <iostream> #include <fstream> using namespace std; #include <Datum.h> // Eller själva koden direkt i filen int main() { Datum d(0, 0, 0); ofstream tsut("datum.txt"); if (!tsut) { cerr << "Kunde inte öppna filen 'datum.txt'.\n"; return 1; } cout << "Skriv datum och avlsuta med filslut." << endl; while (cin >> d) tsut << d << endl; return 0; }
#include <iostream> #include <fstream> using namespace std; #include <Datum.h> // Eller själva koden direkt i filen int main() { Datum d(0, 0, 0); Datum slutdatum(0, 0, 0); ofstream tsut("datum.txt"); if (!tsut) { cerr << "Kunde inte öppna filen 'datum.txt'.\n"; return 1; } cout << "Skriv datum. Avsluta med datumet 0-0-0." << endl; cin >> d; while (!d.lika(slutdatum)) { tsut << d << endl; cin >> d; } return 0; }
#include <iostream> #include <fstream> using namespace std; #include <Datum.h> // Eller själva koden direkt i filen int main() { Datum d1(0, 0, 0); cout << "Skriv ett datum: "; cin >> d1; Datum d(0, 0, 0); ifstream tsin("datum.txt"); if (!tsin) { cerr << "Kunde inte öppna filen 'datum.txt'.\n"; return 1; } int antal = 0; while (tsin >> d) if (d == d1) ++antal; cout << "Datumet " << d1 << " förekom " << antal << " gånger på filen 'datum.txt'.\n"; return 0; }
class Fartyg { private: string namn; Datum byggdes; static Fartyg* first; Fartyg* next; public: Fartyg(string namn, Datum byggdes); virtual void skriv(); virtual int antal_kanoner(); static Fartyg* get_first(); Fartyg* get_next(); };
b) (3p)
Fartyg* Fartyg::first = 0; Fartyg::Fartyg(string namn, Datum byggdes) : namn(namn), byggdes(byggdes) { next = first; first = this; } void Fartyg::skriv() { cout << "Fartyget " << namn << " från " << byggdes << endl; } int Fartyg::antal_kanoner() { return 0; } Fartyg* Fartyg::get_first() { return first; } Fartyg* Fartyg::get_next() { return next; }
c) (1p)
En alternativ lösning:Datum td(1911, 5, 31); Fartyg t((string)"Titanic", td); t.skriv();
Fartyg t("Titanic", Datum(1911, 5, 31)); t.skriv();
d) (2p)
void skriv_alla_fartyg() { Fartyg* p = Fartyg::get_first(); while (p != 0) { p->skriv(); p = p->get_next(); } }
class Slagskepp : public Fartyg { private: int kanoner; public: Slagskepp(string namn, Datum byggdes, int kanoner); virtual void skriv(); virtual int antal_kanoner(); };
b) (2p)
Slagskepp::Slagskepp(string namn, Datum byggdes, int kanoner) : Fartyg(namn, byggdes), kanoner(kanoner) { } void Slagskepp::skriv() { Fartyg::skriv(); cout << "Det är ett slagskepp med " << kanoner << " kanoner." << endl; } int Slagskepp::antal_kanoner() { return kanoner; }
c) (1p)
Funktionen behöver inte ändras alls. Funktionen skriv är virtuell, och därför anropas rätt version i varje fartygsobjekt, trots att det fartygsobjektet anges med en pekare till basklassen Fartyg. Att man (ibland) inte behöver ändra existerande kod som ska arbeta med nya datatyper, är en av fördelarna med objektorienterade språk.
d) (1p)
bool besegrar(Slagskepp s1, Slagskepp s2) { return s1.antal_kanoner() > s2.antal_kanoner(); }
e) (2p)
Datum yd(1940, 8, 8); Slagskepp y((string)"Yamato", yd, 61); Datum id(1942, 8, 27); Slagskepp i((string)"Iowa", id, 158); if (besegrar(y, i)) y.skriv(); else if (besegrar(i, y)) i.skriv(); else cout << "Oavgjort!" << endl;