DD2387 Programsystemkonstruktion med C++ Tentamen 1 Tisdagen den 28 oktober 2014, 08:00-12:00 Introduktion Skriv dina svar på separata papper, dessa scannas in efter inlämning. Du kan skriva på båda sidor. Skriv namn och uppgiftsnummer på varje sida Grova fel ger underkänt, men gör ett försök på alla uppgifter Det är ingen självrättning efter tentan Hjälpmedel En, eller två, valfria läroböcker om C++. 1
1 Sådana där grejer som åker under vatten Det jagas en ubåt. Eller snarare, det efterfrågas information om ett oidentifierat dykande föremål, som det finns en bild på, fast den bilden var på en annan ubåt som man kan hyra för fester. Det finns dock en annan bild, fast den var tagen på en annan plats, eller det beror på, jag kommer inte ihåg. Det är inte lätt att ha koll på den virtuella verkligheten som beskrivs i media men virtual och minneshantering måste man ha koll på i C++. // - - - - - - - - - - - - - - - - - - - - - - - - - - - // Unidentified Diving Object struct UDO { UDO() : origin(this) { virtual void dive() { std::cout << "blubb, blubb" << std::endl; UDO * origin; ; struct MiniUboat : UDO { virtual void dive() { std::cout << "swoosh, swoosh" << std::endl; ; // - - - - - - - - - - - - - - - - - - - - - - - - - - - int main() { MiniUboat boat; UDO & udo1 = boat; UDO udo2 = udo1; udo1.dive(); udo2.dive(); udo1.origin -> dive(); udo2.origin -> dive(); a) Vad skriver ovanstående program ut? swoosh, swoosh blubb, blubb swoosh, swoosh swoosh, swoosh 2
b) Rita minnesbild över hur variablerna boat, udo1, och udo2, ser ut. udo1,boat -> -------- ----------- UDO MiniUboat ---- origin -------- ---------------------- -------- UDO : udo2 ---- origin ---------- 2 Generisk signalspaning Det är inte lätt att jaga ubåtar. Man lyssnar efter sonarsignaler och avgör på något fiffigt sätt om det är minkar, ubåtar, eller något helt annat som låter. a) Skriv en generisk funktion som givet en mängd signaler (definerat av två iteratorer till en godtycklig signaltyp) returnerar första förekomsten av en signal som är minst dubbelt så stor som både den föregående och efterföljande signalen. Gör inget off-by-one fel och kolla så att programmet inte kraschar om man skickar in en för liten (t.ex. tom) mängd. Vad som ska hända om inget element som tillfredställer tidigare beskrivning påträffas är upp till dig, men implementationen är inte godkänd om den krashar vid sådant tillfälle. template <class T> T find(t first, T end) { if ((end - first) < 2) return end; // måste returnera något av typen T, något som kan t for (T i = first + 1; i!= end - 1; ++i) if ((*i >= *(i - 1)*2) && (*i >= *(i + 1)*2)) return i; return end; b) Vad ställer din kod för krav på iteratorerna (parametrarna)? Att man kan subtrahera dem, operator-, addera/subrahera med 1, xoperator++, tilldela, jämföra med!= c) Vad ställer din kod för krav på signaltypen? 3
operator*, operator>= 3 Konsten att använda const a) Varför bör man sträva efter att använda const där så är möjligt i C++? Kompilatorn kan avgöra i compile-time om man försöker skriva till read-only varabler. 4 Att bilda sin egen uppfattning Vad fyller alla de här skriverierna för funktion, objektivt sett? Kan man inte skapa sig en egen bild av situationen igenom att lägga ihop ett och två? Bild f; // a function object double x = f (1, 2); a) Skriv klassen Bild så att ovanstående kod kompilerar. Koden behöver inte göra något vettigt. struct Bild { double operator() (double u, double boat) return u-boat; ; ; 4
5 Kampen mellan journalister Det råder visst en febril verksamhet i media. Mängder med infallsvinklar produceras. En kreativ journalist ger sig ut på spaning med helikopter för att spana på de svenska båtarna som spanar efter det oidentifierade dykande föremålet. En annan skribent spekulerar om den förmodade ubåten kan vara en gigantisk rysk Typhoon som är i sjönöd. Ett rykte som nästan är fakta pekar ut en rysk oljetanker som möjligt moderfartyg efter observationen att fartyget vänt på sig (vilket fartyg som ligger löst för ankar brukar göra). Men kanske ligger tankern därute på internationellt vatten enbart för att slippa hamnavgift. Ja det är många konstiga historier och referenser som cirklar runt. http://www.svt.se/kultur/ubatstrott-eller-ubatspepp Även om det är svårt att hålla koll på medial fakta, så måste man ha koll på const och referenser när man skriver C++. struct Journalist; struct Rumor { bool as_told_by(const Journalist & j); ; struct Journalist { Journalist() { Journalist(const Journalist &) = delete; bool investigate (const Journalist & j, Rumor fact); int story; // Saknades i tentaydelsen int get_story() const { return 1; Rumor drink_beverage_with(const Journalist & j) { Rumor k; return k; void write(int, Rumor, const Journalist &) { ; bool Rumor::as_told_by(const Journalist & j) { return true; bool Journalist::investigate(const Journalist & j, Rumor fact) { if (fact.as_told_by(j)!= 0 ) { this->story = j.get_story(); Rumor more_facts = this -> drink_beverage_with(j); this->write(story, more_facts, j); return true; int main() { Journalist j, k; Rumor r; j.investigate(k, r); a) Skriv den implementation som saknas (så att ovanstående kod kompilerar). 5
Observera att man inte kan kopiera journalister. Koden behöver inte göra något vettigt. 6
6 En destruktiv jakt En del tycker att den pågående jakten efter oidentifierade undervattensfarkoster är rent destruktiv. En cprog-student observerar att destruktorn är helt åt fanders. struct Hunt { std::vector<udo *> * v; Hunt() { v = new std::vector<udo *>(); void seek(water w) { while (w.suspicous()) { Sound s = w.listen(); if (s!= w.normal()) v -> push_back(new UDO(s)); ; ~Hunt() { delete [] v; a) Vad är problemet/problemen med destruktorn i Hunt? Det är två problem. 1) Det är fel delete, det ska inte vara [] 2) Eftersom klassen allokerar minne för pekare som läggs till vektorn bör destruktorn loopa igenom och ta bort dessa b) Hur borde destruktorn skrivas? for (auto i : *v) delete i; Man kan tänka sig att det görs i en clear-funktion men loopen måste nämnas c) Vilka automatiskt genererade medlemsfunktioner brukar ingå i det som tidigare (c++98) kallades för "Rule Of Three"? operator=, copy-constructor, destructor 7