struct A {
A() { cout << "A()"; }
˜A() { cout << "˜A()"; }
A(const A &) { cout << "A(A)"; }
virtual void foo() { cout << "A::foo()";
};
struct B : public A {
virtual void foo() { cout << "B::foo()";
};
A a;
B t;
B b = t;
A aa[3] = {a, b};
A &ar1 = aa[1];
A &ar2 = b;
ar1.foo();
ar2.foo();
Vad skriver programmet ut n ¨ar man k ¨or det? Ge en kom- mentar f ¨or varje rad f ¨or att motivera ditt svar. 10p
Tentamen oktober 2005 tal 4
I koden f ¨or textspelet monsterspel finns en spelarklass och en monsterklass som ¨arver av Actor. Det finns flera sub- klasser till monsterklassen; troll, vargar m.m. som l ¨ases in i en monstervektor via funktionen.
vector<Monster *> LoadMonsters(string filename) { /*
Spelet fungerar att spela men spelaren d ¨or alldeles f ¨or l ¨att vid monsterstrider. Man har d ¨arf ¨or nyligen lagt till en metod som ska testa strider med de olika monstren.
void test_fighting(vector<Monster *> monsterlist) { vector<Monster *>::iterator i;
for (i = monsterlist.begin(); i != monsterlist.end() Spelare spelare("Testspelare", 120, 18, 18);
fight(&spelare, *i);
} }
Spelet kraschar med den nya koden. Du f ˚ar i uppgift att titta p ˚a fightkoden och utr ¨ona vad som ¨ar galet.
void fight(Actor * hitting, Actor * receiving) { bool dead = false;
while (! dead) {
dead = hitting->hit(receiving);
delete receiving;
}
swap(hitting, receiving);
} }
1. Beskriv utf ¨orligt varf ¨or programmet kraschar? 2p
2. Beskriv med en mening varf ¨or programmet kraschar?
1p
3. ¨Aven om koden p ˚ast ˚as fungera felfritt om test fighting inte ¨ar med s ˚a kan man misst ¨anka att det kvarst ˚ar pro-
blem. Vad f ¨or problem? 2p
Tentamen oktober 2004 tal 3. Ett pensionsf ¨ors ¨akringsbolag har problem med sina rutiner. Ibland f ¨orsvinner gamla kun- der of ¨orklarligt. Man misst ¨anker sitt nya datasystem.
class Datasystem { private:
Customer * customers;
unsigned long nr_of_customers;
unsigned long customer_capacity;
public:
void add_customer(Customer a) { nr_of_customers++;
if (nr_of_customers >= customer_capacit customers = new Customer [customer_
}
customers[nr_of_customers] = a;
}
// ...
a) F ¨orklara kortfattat (h ¨ogst ett par meningar) vad som ¨ar galet med add customer.
som ¨ar galet med add customer.
c) Skriv en f ¨orb ¨attrad version av add customer. Ta inte hand om fallet att minnesallokering kan misslyckas.
d) Om man nu skulle vilja f ˚anga minnesallokeringspro- blem och rapportera problemet hur skulle man b ¨ara sig ˚at d ˚a? Motivera ditt f ¨orslag.
e) Klassen Datasystem hanterar dynamiskt minne. Du best ¨ammer dig f ¨or att kodkontrollera resten av klas- sen. Vilka metoder b ¨or du leta efter? Hur b ¨or koden i dessa metoder se ut?
15p
auto_ptr : Ett f ¨ orsta exempel
auto_ptr ¨ar en typ av “intelligent” pekare. Id ´en ¨ar att auto_ptr-objektet ser till att en pekare blir delete:ad n ¨ar dess destruktor k ¨ors.
#include <memory>
2 class A { public:
4 A(int v) : value(v) {}
int value;
6 };
/ / w i t h o u t a u t o p t r
8 void foo( ) {
A ∗ap = new A( 4 ) ;
10
/∗ kod som kanske kan ge e x c e p t i o n s ∗/
12
delete ap;
14 }
/ / w i t h a u t o p t r
16 void bar( ) {
auto_ptr<A> ap(new A ( 4 ) ) ;
18 /∗ kod som kanske kan ge e x c e p t i o n s ∗/ }
1
Varje auto_ptr-objekt pekar antingen p ˚a ett objekt eller null.
Programmeraren m ˚aste ¨aven se till att varje objekt pekas p ˚a av h ¨ogst ett auto_ptr-objekt.
Vid tilldelning eller kopiering ¨overf ¨ors ¨agandet av en peka- re. Anv ¨and const-deklarering f ¨or att f ¨orhindra tilldelningar och k ¨orning av kopieringskonstruktorn.
#include <i o s t r e a m>
2 #include <memory>
#include <s t r i n g >
4 #include <c s t d d e f>
using namespace std;
6 class Person { public:
8 string ∗name; string ∗persnr;
10 Person(char ∗na, char ∗no) : name(new string(na) ) ,
12 persnr(new string(no) ) { }
˜Person( ) {
14 delete name, delete persnr; } };
2
auto_ptr : Medlemsvariabler
Ett viktigt anv ¨andningsomr ˚ade f ¨or auto_ptr ¨ar f ¨or att f ¨orhindra minnesl ¨ackor. I f ¨oreg ˚aende exempel g ¨ors en far- lig konstruktion i detta h ¨anseende. Vilken?
Nedan illustrerar vi hur s ˚adana farligheter kan undvikas enkelt med auto_ptr.
#include <i o s t r e a m>
2 #include <memory>
#include <s t r i n g >
4 #include <c s t d d e f>
using namespace std;
6 / / w i t h a u t o p t r members class APPerson {
8 private:
const auto_ptr<string> name;
10 const auto_ptr<string> persnr; public:
12 APPerson(char ∗na, char ∗no) : name(new string(na) ) ,
14 persnr(new string(no) ) { }
16 ˜APPerson( ) { } };
3
#include <memory>
2
std : : auto_ptr<BigObj> a(new BigObj ( ) ) ;
4 std : : auto_ptr<BigObj> b;
6 b.get ( ) ; / / NULL b = a;
8 a.get ( ) ; / / NULL
a = std : : auto_ptr<BigObj>(new BigObj ( ) ) ;
10 a−>doBigObjStuff ( ) ;
std : : cout << ∗a;
12 ∗a = ∗b; / / ¨andra a : s o b j e k t s v ¨arde a = b; / / ge a b : s o b j e k t
4
auto_ptr: Varningar
• Tyv ¨arr funkar auto_ptr ej f ¨or arrays. Varf ¨or?
/ / Vad s k u l l e d e t t a betyda ?
2 void foo ( ) {
auto_ptr<char> vec(new char[ 1 0 ] ) ; / / e j OK!
4 }
• Flera auto_ptr-objekt f ˚ar inte initieras med samma pekare.
Om man g ¨or det s ˚a kommer det f ¨orst destruerade
auto_ptr-objektet delete:a det “gemensamt ¨agda”
objektet.
• Det finns andra s ¨att att tillverka “smarta pekare” som r ¨aknar antalet referenser till objekt. Detta kan ses som en begr ¨ansad form av skr ¨aphantering.
auto_ptr skall ej f ¨orv ¨axlas med detta.
5