Tentamen i 2D1387 Programsystemkonstruktion med C++
Datum: Lördag 21 oktober 2006, 09-13
Hjälpmedel: En eller två valfria läroböcker om C++
Tid: 4 timmar
Alla rätt ger 6 bonuspoäng. Grova fel ger underkänt (betyg U). Om inte alltför många grova fel görs ges möjlighet att komplettera till godkännt betyg(betyg U*
eller FX)mer information om komplettering kommer att stå på kurshemsidan.
Gör ett försök på alla fyra uppgifter. Tentaresultat anslås inte enligt längre på anslagstavla i enlighet med ny policy från KTH centralt. Lycka till!
1. Det bakvända samhället
Det sägs att dagens samhälle är alldeles bakvänt i somliga hänseenden.
För att ta reda på om så verkligen är fallet ska du skriva en funktion som analyserar innehållet i olika samhällsprogram och tar reda på om det finns något bakvänt.
Skriv en funktion backwards som tar tre parametrar; en iterator som anger början på ett inslag, en annan iterator som anger slutet på ett annat inslag samt en längd (unsigned int)som anger hur mycket som ska undersökas.
Funktionen ska returnera true om samma data återfinns i omvänd ordning annars false.
Funktionen ska vara typparametriserad och även kunna anropas med en heltalsvektor enligt följande exempel vilket förhoppningsvis också klargör hur funktionen är tänkt att fungera.
int vek [] = {1, 2, 3, 4, 2, 3, 4, 3, 2, 1};
if (backwards(vek, vek + 3, 2)); else cout << "false 1,2 != 4,3" << endl;
if (backwards(vek, vek + 9, 3)) cout << "true 1,2,3 == 1,2,3" << endl;
if (backwards(vek, vek + 9, 5));
else cout << "false 1,2,3,4,2 != 1,2,3,4,3 " << endl;
2. Virtuell verklighet
Att saker och ting är bakvänt får sin förklaring i filmen the Matrix. Om jag förstod filmen rätt så lever vi egentligen i en virtuell verklighet. Hur vir- tuella funktioner fungerar i C++ måste man verkligen kunna. Vad skriver följande program ut?
struct TheMatrix {
virtual TheMatrix foo() {
cout << "TheMatrix::foo() "; return *this;
} };
struct TheWorld : TheMatrix { virtual TheMatrix foo() {
cout << "TheWorld::foo() "; return *this;
} };
1
int main() {
TheWorld world;
TheMatrix matrix = world;
TheMatrix & ref = world;
cout << endl << "a) "; world.foo();
cout << endl << "b) "; matrix.foo();
cout << endl << "c) "; ref.foo();
cout << endl << "d) "; ref.foo().foo(); cout << endl;
}
3. Mer om matriser
För att implementera alla parallella verklighter som finns enligt filmen, så behövs antagligen en matrisklass. Nedan finns en sådan implementation.
class Matrix { int rows, cols;
int * vec;
public:
Matrix () : rows(4000), cols(4000) { vec = new int[rows * cols];
for (int i = 0; i < rows * cols; i++) vec[i] = 0;
}
Matrix (int x, int y) : rows(x), cols(y) { vec = new int[rows * cols];
for (int i = 0; i < rows * cols; i++) vec[i] = 0;
}
Matrix (const Matrix & m) { rows = m.rows;
cols = m.cols;
vec = new int[rows * cols];
for (int y = 0, i = 0; y < rows; y++) for (int x = 0; x < cols; x++, i++)
vec[i] = m(x, y);
}
int operator() (unsigned int x, unsigned int y) const { assert(x < rows && y < cols);
return vec[y * rows + x];
}
int & operator() (unsigned int x, unsigned int y) { assert(x < rows && y < cols);
return vec[y * rows + x];
}
friend ostream & operator<<(ostream & os, const Matrix & m);
};
(a)Verkligheten blir ganska enahanda om man bara kan fylla matrisen med heltal. Typparametrisera matrisklassen så att godtycklig typ kan rymmas däri. Låt defaultkonstruktorn initiera de 16 miljoner elementen till defaultvärdet för typen.
2
(b)När verkligheter skapas lokalt här och där så verkar det som att det i det stora hela läcker minne. Kanske är det därför vi har svarta hål i tillvaron. En luttrad student från 2D1387 ser dock att det saknas ett par vitala metoder i vår matrisklass. Vilka metoder bör man lägga till i matrisklassen?
(c)Implementera de metoder som bör läggas till.
(d)Apropå minne är det inte säkert att det räcker till i skapandepro- cessen. I undantagsfall kanske man bör upplysa skaparen om det.
Konsultera din medhavda litteratur och beskriv hur man fångar un- dantaget att minnet är slut vid konstruktion av matrisklassen.
(e)Om klassen TheMatrix har en matrix som instansvariabel kan det vara värt att initialisera matrisen i initieringslistan, varför?
(f)Ute i världen finns det svartklädda agenter som försöker lägga ihop ett och annat. De vill att du implementerar en operator+-metod.
Matrix & operator+(const Matrix &);
En erfaren C++-programmerare förklarar skrattande att en kedjere- aktion skulle kunna resultera i förvrängda verkligheter. Vad är det som är tokigt i ovanstående metoddeklaration?
(g)Deklarera ett par (2)ytterliggare operatorer, förutom de som redan deklarerats. Operatorerna ska kunna vara användbara för en matris- klass. Förklara med text hur de ska fungera och vad de ska returnera.
(h)Definiera operatorer är det inte alla programspråk som kan. Vad vin- ner man på att kunna definiera operatorer?
4. Tilldelning av resurser
Verkligheten är ojämlik. Det kan bero på att tilldelningen av världens resurser inte är optimal. Det är viktigt att förstå hur tilldelning fungerar i C++.
(a)Vad skrivs ut av nedanstående program?
(b)Skulle det bli någon skillnad om samtliga tilldelningsoperatorer var deklarerade virtual?
(c)Om man explicit vill anropa tilldelningsoperatorn i sin basklass hur gör man det? Skriv in ett sådant anrop i tilldelningsoperatorn för B.
struct B;
struct A {
A & operator=(const A & arg) {
m = arg.m; // m tilldelas !!!
cout << "A::operator=(A) körs " << endl; return *this;
}
A & operator=(const B & arg) {
cout << "A::operator=(B) körs " << endl; return *this;
} int m;
};
3
struct B : A {
B & operator=(const A & arg) {
cout << "B::operator=(A) körs " << endl; return *this;
}
B & operator=(const B & arg) {
cout << "B::operator=(B) körs " << endl; return *this;
} };
struct C : B { };
int main() {
A a; B b; C c;
a.m = 10; b.m = 11; c.m = 12;
cout << "1) a = a; "; a = a;
cout << "2) a = b; "; a = b;
cout << "3) b = a; "; b = a;
cout << "4) b = b; "; b = b;
cout << "5) b = c; "; b = c;
cout << "6) a = c; "; a = c;
cout << "7) a.m = " << a.m << endl;
cout << "8) b.m = " << b.m << endl;
cout << "9) c.m = " << c.m << endl;
}
Rudementary english translation
1. Write a template function named backwards that takes three parameters where first is beginning of a sectiom, second is the end of another section and third is how far to compare. If the sections contains the same items (counted from each end)true is returned, else false.
2. What does the program print?
3. (a)Change class Matrix into a template class and let the default con- structor initialize each element with the default value of the contained type.
(b)What methods should be added to avoid memory leaks?
(c)Define the methods to be added.
(d)How do you catch out of memory when constructing the matrix?
(e)What do you gain by initialing a matrix instance variable in the initialization list?
(f)What’s wrong with the plusoperator method decklaration?
(g)Declare and describe two more operator methods not already defined (h)What do you gain by being able to declare operators?
4. a)What is the program output? b)Does it make any difference if all methods were virtual? c)Write an explicit call inside B assignment method that call its base class assignment operator.
4