• No results found

Lösningsförslag i 2D1387 Programsystemkonstruktion med C++ 1.

N/A
N/A
Protected

Academic year: 2021

Share "Lösningsförslag i 2D1387 Programsystemkonstruktion med C++ 1."

Copied!
4
0
0

Loading.... (view fulltext now)

Full text

(1)

Lösningsförslag i 2D1387 Programsystemkonstruktion med C++

1. virtual-deklarationen av speak medför att det blir subklassens implementa- tion av speak som körs. I anropet till make_a_statement_cop kopieras endast basklassdelen.

Sammanslagningen ger synergieffekter Det står på agendan

Nu måste vi fokusera på kärnverksamheten Nu måste vi fokusera på kärnverksamheten Sammanslagningen ger synergieffekter

2. När man skriver mallar måste man tänka på vilka krav man ställer på sina typparametrar. I första fallet kan vi anta att de vanliga operatorerna är defini- erade.

template <class T>

int gallra(T * begin, T * end, int s) { int retur = 0;

for (T * i = begin; i != end; i++) { if (*i >= s) retur++;

}

return retur;

}

I det andra fallet måste vi själva deklarera det jämförande funktionsanropet.

Nedan finns några förslag. Beroende på hur man skriver jämförelsen kan det bli en metod i endera klassen eller kanske en fristående funktion. Jag tycker det är sämre att lägga metoden i vektorelementets klass men jag kan godkänna bra motiveringar.

template <class T, class S>

int gallra(T * begin, T * end, S s) { int retur = 0;

for (T * i = begin; i != end; i++) {

if !(*i < s) retur++; // kan skrivas (s < *i) }

return retur;

}

class T {

bool operator< (B b) // Vektorvärdena måste känna till B // ...

class B {

bool operator< (T t) // Jämförelseklassen känner till vektorvärdet // ...

bool compare(B b, T t) // Funktionen känner till båda

1

(2)

3.

a) Det finns flera fel med den här metoden. Dels så kopieras aldrig gamla kunder över till nya vektorn, dels så avallokeras inte den gamla vektorn vilket betyder att metoden läcker minne, dels så uppdateras inte custo- mer_capacity. En kortfattad formuleringen skulle kunna vara. Metoden tappar gamla kundvektorn och läcker minne

b) Det är framför allt if-saten som är tokig och behöver illustreras.

if (nr_of_customers >= customer_capacity) {

customers = new Customer [customer_capacity * 2];

c) Se push_back i lab1.

d) Man behöver fånga bad_alloc med ett try/catch-block. För att skicka vidare kan man antingen kasta vidare ett annat undantag eller så kan man returnera något om man ändrar void i metodhuvudet. Det kan vara en god ide att skicka med kundens data (Customer a) i undantaget eller i returvärdet.

Assert är fel sätt i det här fallet eftersom det avbryter programmet möjli- gen skulle det kunna godkännas med en bra motivering och rapportering i en logfil.

e) Titta i konstruktorerna, kolla om de allokerar minne. Titta speciellt efter copy-konstruktorn. Den bör se ut som i lab1 vektorklass. Kolla att de- struktorn kör delete [] på customers. Kolla efter operator= som kommer att se ut ungefär som i lab1 vektorklass.

2

(3)

4.

a) Referensräkning med copy-on-write är en teknik för att spara minne i strängklassen. Istället för att alltid allokera nytt minne för varje namn så kan strängar med samma innehåll dela ett minnesutrymm. Till det behövs en hjälpklass som allokerar minnet och som har en referensräknare (en instansvariabel) som håller reda på hur många strängar som refererar den.

b) s2 = s1; // operator=

char c = s2[5]; // operator[] const s2[5] = ’L’; // operator[]

s2 = s1;

Metoden operator= ska i basfallet sätta om this att peka ut parameterns minnesutrymme. Dessutom räkna ner sin föregående referensräknare och räkna upp den andra.

Om referensräknaren når noll ska minne frigöras med delete.

Det är som vanligt bra att ta hand om specialfallet:

s1 = s1;

s2[5] = ’L’;

Den sista radens operator[] skriver i strängen. Alltså måste vi allokera nytt minnesutrymme och kopiera över strängen innan vi skriver i det nya minnesutrymmet. Det är detta som är copy-on-write.

char c = s2[5];

Om vi bara ska läsa i strängen är det onödigt att kopiera till en ny sträng.

Därför vill vi ha en operator[] const.

3

(4)

c) Båda pekar på samma minnesutrymmet men p1 är const-deklarerad och får inte ändra på minnesutrymme. Därför kommer operator[] const (se b) att anropas.

d) Med p2 kan man få problem med våran referensräknarklass. Visserligen sker ingen skrivning till strängen men strängklassen kan inte skydda sig mot *p2 = ’X’;

f ) Man kan tänka sig att operator[] alltid kopierar till nytt minne. Då kan man inte garantera konstant tid för: char * p2 = &s1[5];

Man kan tänka sig en statusflagga i klassen och kopiera senare.

e) p1 är read-only och kan inte skriva i strängen.

4

References

Related documents

• Skriv metoden bool move_event(const Date &amp; from, const Date &amp; to, std::string event) som kan flytta händelser i kalendern genom att först plocka ut och sedan lägga

c) Både deklaration och definition för bar och baz är korrekta trots att de inte överensstämmer helt. Vad är orsaken till att detta är tillåtet? 3p d) Trots påståendet i uppgift

const A &amp; ger två olika överlagringar av funk- tionen boo eftersom de två överlagringarna exponerar olika gränssnitt för an- vändaren (det ena kan ändra indatat, det andra

på åtgärd där så är möjligt. För att minska kompileringstiderna och underlätta underhåll vill man undvika beroenden mellan klasser. Vi vill utöka klassen B genom att

Obs: Dessa lösningar är just lösningsförslag.. A-objektet måste allokeras dynamiskt, vilket kan ta tid om det blir många små objekt som ska allokeras och avallokeras. Det

b) Varför kan inte definitioner ligga i headerfilen? 3p c) inline och template är undantag från regeln i deluppgift b). Varför måste. dessa ligga i

b) Vilka effekter uppnås genom att göra konstruktor, destruktor, kopierings- konstruktor, tilldelningsoperator samt operatorerna new och delete till protected

Du vill skapa en trådklass Thread med följande egenskaper: Thread ska när tråden räknat klart frigöra sig själv och får därför inte allokeras på stacken. Trådens arbete ska