Vinnaren i pepparkakshustävlingen!
  • 1
  • 2
2019-08-30, 18:39
  #13
Medlem
Citat:
Ursprungligen postat av keysersozeswe
Yes den har stöd för det och det är min lärare som säger PersonLista saknar en överlagrad tilldelningsoperator.

En notering här är att om du kör med gammal C++-standard så behöver du tänka på rule-of-three.

Om ditt objekt innehåller data som inte kan korrekt hanteras med kopiering fält-för-fält så behöver du skriva egen kod för detta. Pekare är ett exempel på ett fält som inte klarar vanlig kopiering, för kompilatorn kommer att kopiera pekaren i stället för att förstå att det behövs en minnesallokering och sedan en kopiering av informationen från den ena minnesbufferten till den andra.

Så då behöver du en copy-constructor (som alltså korrekt tar kopia från annat objekt av samma typ direkt vid initiering).

Och du behöver en assignment-operator för att hantera vanlig tilldelning var = other_var;

Och du behöver en destruktor som förstår att frisläppa minnesblocket (och ev rekursivt data i objekt som lagras i minnesblocket).

https://en.wikipedia.org/wiki/Rule_o...2B_programming)

Person behöver inte bry sig, för den har inget attribut av någon typ som inte kan direkt hantera direkt tilldelning.

PersonLista saknar i koden du laddade upp en assignment-operator. Den har copy-constructor och destructor men alltså inte hela trefaldigheten.

Transaktion har assignment-operator och destruktor. Men ingen copy-constructor. Alltså möjlighet till läckage med string* vanner.

TransaktionsLista saknar både tilldelningsoperator och kopierings-konstruktor. Men eftersom ditt program inte behöver kunna kopiera en transaktionslista så skulle du kunna lösa det utan att implementera. Med äldre standard på c++ så kan du lista en assignment operator och en copy-constructor som private och sedan låta bli att implementera. Då kommer kompilatorn åtminstone ge ett kompileringsfel (eller möjligen länkfel) om programmet faktiskt försöker göra en kopia på en transaktionslista.

Edit:
och med färskare C++ behöver du inte gömma assignment operator eller copy constructor i private. Du kan i stället skriva "= delete;" efter deklarationen för att säga att du inte tänker implementera funktionen och att kompilatorn själv absolut inte får default-generera någon åt dig.
__________________
Senast redigerad av cellplast 2019-08-30 kl. 18:41.
Citera
2019-09-01, 04:22
  #14
Medlem
Lite utanför frågeställningen eftersom jag saknar kompilator på denna kärran, men ett par tips här:

Om man är osäker på const deklarationer så är det ett ganska bra trick att skippa alla consts i dina deklarationer, i den allra första designrundan, och kolla att koden kompilerar okej.
Därpå kan du börja föra in const på dem du behöver.
Läs noga på sådana exempel, tex var const ska stå mm.
Övning ger färdighet
Man brukar inte vinna något prestandamässigt precis på att utnyttja varje möjlighet till const
därför får man i den reella verkligheten av redan färdigskriven kod se massor av sådana deklarationer där det mesta som eventuellt skulle kunnat deklarerats som const - där har const utelämnats.
En del programmerare tycker det är onödigt med const eftersom de redan kan programmera och gör sällan sådana fel som kunde uppdagats med en const deklaration.

OT - Svammel: Ett annars intressant specialfall inträffar ifall du måste konvertera en länkad lista till en stream, och tex omvänt, och pekarna i objekten och till objekten blir ju invalida (ogiltiga) eftersom en stream inte har samma adressutrymme som inne i RAM. Eller ja man kan säga att inga pekare kan förekomma inne i en stream. Eftersom man inte kan veta fpos i förväg innan objektet är skrivet, och flushat till disk. Finns ett antal metoder att komma runt detta, med att streama.
Tog upp detta eftersom det är en slags copy constructor att hämta innehållet ifrån en stream
Stream i C++ är alltså filer och operatorerna << och >> är avsedda att användas för läsning resp skrivning till fil
I databaser så kan det vara frekvent förekommande att skriva objekten på fil, man löser det nästan alltid med fasta fält, och inga dynamiska objekt såsom strängar av godtycklig längd förekommer.

Cellplast har förklarat mycket bra i förra inlägget hur du ska angripa problemet och detta inlägg ska bara ses som ett ytterligare tips, ja en slags fördjupning på copy konstruktor problemet.

Och på många kurser vill man att deklarationer av kompletta klasser också att det ska finnas med stream operatorerna.
Varför ?
Jo i många produktionsprogram så krävs det att man kan spara (hela) programtillståndet/programdata på fil, dvs flusha ut det på en stream. Som sedan kan återhämtas ifrån disk då programmet startas igen. Och då är stream operatorerna mycket smidiga att använda, vare sig det är objekt som ska skrivas ut, eller tex hela listor - Och man får vanligen ta och tänka efter ganska noga kring hur man bäst skriver dessa operatorer << >>
Citera
2019-09-02, 22:44
  #15
Medlem
Fösöker verkligen men har sprungit in i en betongvägg med mitt ägghuvud nu. Egentligen även om hela koden är allt utom perfekt (jag vet) så klagar läraren på att PersonLista inte har en överlagrad tilldelningsoperator, och när jag gör det får jag fler fel. Önskar bara avsluta men hur jag än gör så går jag runt problemet med fler fel
Mvh,
Korkskallen
Citera
2019-09-03, 01:40
  #16
Medlem
Citat:
Ursprungligen postat av keysersozeswe
Jag testade med;
PersonLista & operator = (const PersonLista & p);

Då åker jag på:
290|error: definition of implicitly-declared 'PersonLista::PersonLista(const PersonLista&)'|

På följande rad:
PersonLista::PersonLista(const PersonLista & pl)
:antal_personer (pl.antal_personer)

Som sagt, jag är helt rookie på detta och verkligen sliter med att förstå, men framförallt så måste jag lämna in uppgiften men springer in i väggen hela tiden.

TACK för din tid och ditt tålamod!

Prova att skriva efter den här exempelkoden här:

Copy constructor vs assignment operator in C++
Difficulty Level: Rookie

Consider the following C++ program:
#include<iostream>
#include<stdio.h>

using namespace std;

class Test
{
public:
Test() {}
Test(const Test &t)
{
cout<<"Copy constructor called "<<endl;
}

Test& operator = (const Test &t)
{
cout<<"Assignment operator called "<<endl;
return *this;
}
};

// Driver code
int main()
{
Test t1, t2;
t2 = t1;
Test t3 = t1;
getchar();
return 0;
}

Finns på länken här:

https://www.geeksforgeeks.org/copy-c...operator-in-c/

Det finns också en del specialfall som man brukar ha som en extra svårighetsgrad i tex en tenta och det är hur dessa operatorer och konstruktorer ska hantera tomma listor utan några medlemmar i.
Tips är att sätta sig in i hur this fungerar, det syntaxordet är mycket värdefullt i C++
Citera
2019-09-03, 02:05
  #17
Medlem
Har tyvärr ingen hjälp att ge men jag kämpar själv med samma uppgift så jag följer denna tråd för att se om något hjälpsamt dyker upp!
Citera
2019-09-07, 21:38
  #18
Medlem
Transaktion & operator = (const Transaktion & tn);

måste deklareras utanför klassen alt så är det så att

Transaktion & operator = (const Transaktion & tn); skall stå som
void operator = (const Transaktion & tn);

Sedan är detta deklarationer, ser ingen implementation, cpp filen?
__________________
Senast redigerad av sampanl 2019-09-07 kl. 21:53.
Citera
2019-09-08, 20:45
  #19
Medlem
kaks avatar
Citat:
Ursprungligen postat av sampanl
Transaktion & operator = (const Transaktion & tn);

måste deklareras utanför klassen alt så är det så att

Transaktion & operator = (const Transaktion & tn); skall stå som
void operator = (const Transaktion & tn);

Sedan är detta deklarationer, ser ingen implementation, cpp filen?
En överlagrad tilldelningsoperator får inte deklareras utanför klassen utan måste vara en medlemsmetod.
Den får ha vilken returtyp som helst, men etablerad praxis är att returnera en referens till den tilldelade instansen.

Kod:
struct X {
    
Xoperator=(const X&);
};

XX::operator=(constXrhs) {
    
// Kopiera innehållet
    
return *this;

Citera
2021-07-22, 13:46
  #20
Medlem
Ja eftersom du saknar en överlagrad tilldelningsoperator.
Citera
2021-07-25, 05:13
  #21
Medlem
Bara ett tips, const tar lite tid att lära sig det i början.
Syntaxen kan se konstigt ut om det är för konstiga const i koden.
Bäst att skippa const tills att du har lärt det dig hur det fungerar och känner dig pigga på att experimentera vidare.

Näst efter pekararitmetik och hantering av pekare, new och delete, så brukar const ställa till mycket huvudbry för många newbies. Överanvänd alltså inte const - särskilt inte då det inte behövs.
Citera
  • 1
  • 2

Stöd Flashback

Flashback finansieras genom donationer från våra medlemmar och besökare. Det är med hjälp av dig vi kan fortsätta erbjuda en fri samhällsdebatt. Tack för ditt stöd!

Stöd Flashback