[an error occurred while processing this directive] [an error occurred while processing this directive][an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive] (none) [an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive][an error occurred while processing this directive] [an error occurred while processing this directive][an error occurred while processing this directive] [an error occurred while processing this directive][an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive] (none) [an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive][an error occurred while processing this directive]
 
[an error occurred while processing this directive] [an error occurred while processing this directive]
Skåne Sjælland Linux User Group - http://www.sslug.dk Home   Subscribe   Mail Archive   Forum   Calendar   Search
MhonArc Date: [Date Prev] [Date Index] [Date Next]   Thread: [Date Prev] [Thread Index] [Date Next]   MhonArc
 

Re: [PROGRAMMERING] [C++] new class, fail. Ønskes: NULL pointer



On Tue, Jan 13, 2004 at 10:25:46PM +0100, Peter Maersk-Moller wrote:
> Hans Schou wrote:
> 
> >Hmm, nok fordi jeg ikke lige vidste hvordan man gør det.
> >
> >Måske jeg skulle købe en bog om C++ :-)
> >
> 
> Hvis du ikke er saa fanatisk, saa er der ikke saa langt fra C tilC++.

Ok, kald mig bare fanatisk, men jeg er rigtigt uenig i det du siger  ;)

Jeg kan gå med til: "hvis du ikke gider lære C++ men kan C, så er det
meste C kode også gyldig C++".

> Spender 69 kr paa 
> http://www.libris.dk/default.asp?loadside=/Vis_produkt.asp?ISBN=87-7843-265-0
> Hvis det er for meget (og hvis du forstaar contructor og faar lidt hjaelp
> med arv og klasser), saa laes kap. 6 her 
> http://www.libris.dk/webfiler/877843/265/kap6.pdf

Jeg kommer altså lige med en mindre anmeldelse - skip den hvis du har
travlt  :)

Der er en summering til slut...   Jeg slettede ca. halvdelen af mine
kritik-punkter for at få mailen lidt ned i størrelse.


Makroer
===================

Starter ud med at lære folk at bruge makroer til konstant
definitioner...

Makroer har eet formål i C++, og eet formål kun: include guards.
(jeg har een undtagelse til den regel, men det rager for vidt at
 beskrive det her - lad mig bare sige, at det er et special-tilfælde)

C++ gør det netop muligt at skrive f.eks. 'const int MOMSPROCENT = 25;'
i din headerfil, istedet for '#define MOMSPROCENT 25' som er C måden at
opnå næsten det samme på (dog uden typesikkerheden som gør C++ så meget
lettere at skrive pålidelig kode med).

Dernæst: inkluderer 'iostream.h' - som er et levn fra gamle dage. Den
hedder 'iostream' - og 'cout' m.v. findes i 'std' namespacet - at bruge
'iostream.h' i dag er fjollet.

Makro-eksemplet med '#define KUBUS ((x)*(x)*(x))' gør det ikke meget
bedre - hvorfor skal en begynder lære at sætte ekstra paranteser for at
arbejde uden om pre-processorens begrænsninger?  I C++ ville man blot
skrive 'inline int kubus(int x) { return x * x * x; }' - skidtet ville blive
inlinet af enhver fornuftig compiler, det er typesikkert, det overholder
namespace regler (som pre-processoren af gode grund ingen chance har for
at overholde), og det er en helt almindelig funktions deklaration -
altså ingen grund til at lære begynderen både at deklarere 'små'
funktioner som makroer og større som 'rigtige' funktioner.  Hold det dog
simpelt - for det kan man nemlig i C++.

Afsnittet 'Forskelle mellem makroer og funktioner' starter ud med noget
som er 100% sludder og vrøvl. Forfatteren har åbenbart aldrig hørt om
'inlining' eller 'optimerende compilere'.

Det opfølges af en sand perle: 'MAKPAUSE.CPP' programmet - som flot
viser nybegynderen hvordan man laver et delay i et program: jo, man
tæller til en milliard, så skal computeren nok holde en tænkepause...
Jeg har kun een gang før set noget lignende i undervisningsmateriale -
der er simpelt hen ingen undskyldning for det.  1) man busy-waiter bare
ikke (i mere end nogle få nano/mikro-sekunder ihvertfald), og man har
ikke gjort det på 'moderne' operativsystemer de sidste 40 år. 2) Koden
vil slet ikke give et delay, på enhver moderne optimerende compiler - da
den simpelthen vil optimere løkken ud!  Jovist jeg er klar over at det
ikke er en guide til at lære folk at programmere 'optimalt', men det er
da fuldstændigt ude i hegnet at give folk et eksempel som er absurd
dårlig stil, og på en moderne compiler slet ikke kan virke.


Brug af free store
==================

Vi starter med at lære, at 'new' returnerer NULL hvis den ikke kan
allokere den efterspurgte plads.   Sludder og vrøvl.

'new' smider en 'bad_alloc' exception hvis den ikke kan allokere plads -
det er rigtigt at den returnerede 0 en gang for ca. 10 år siden - men
den har ikke returneret 0 så længe som C++ har været standardiseret.

Og så lidt nit-picking; NULL findes ikke i C++. Brug 0.  Det er lettere
at forstå, kortere at skrive, pænere, og kan potentielt løse nogle
problemer når man porter sin kode.

Det bliver bedre undervejs: under 'Frigivelse af lagerplads efter brug'
lærer vi nu at vi kan frigive et array af elementer (allokeret med
'new[]'), ved at kalde 'delete'.  Læg mærke til, at det ikke er
'delete[]' der kaldes...  Det betyder, at for eksempler der ikke lige
arbejder med 'char' eller andre simple typer som i det givne eksempel,
vil konstruktøren på de enkelte elementer blive kaldt, mens destruktøren
aldrig vil blive kaldt.  Flot. Lad os lære folk at lække ressourcer -
nutidens computere er alligevel så store at ressource-læk ikke har
betydning - eller noget...

At han så laver eksempler for begynderen, med char arrays og strcpy()
gør det ikke meget bedre.  Hvis det ikke er en avanceret bog, hvorfor så
ikke holde sig til std::string som man da i det mindste ikke kommer lige
så frygteligt galt afsted med som forfatteren selv gør her med hans egne
eksempler...?

Jeg begriber ikke hvorfor man skal pine en begynder med noget af det som
netop er relativt svært for begyndere at forstå i C, når netop C++
tilbyder effektive måder at løse de samme problemer på langt mere
sikkert. Hvorfor ikke vise folk std::string og std::vector, istedet for
at lære dem hvordan man (fejlagtigt tilmed) bruger new[] og delete?
Hvorfor lære folk char arrays og strcpy(), når std::string og '=' kan
gøre det samme, blot uden leaks og hukommelses-fejl.

'Vi skriver vores egen new og delete' - og lærer begynderen hvor
fantastisk det er at lave C-style casts...  Har han ikke hørt om
'static_cast' og 'reinterpret_cast' - static_cast er mere streng end
C-style casts, og der er derfor 'farlige' situationer som man ikke kan
bruge den i - modsat C-style casts som gladeligt caster hvad som helst.
Har man et problem i et 'rigtigt' C++ program kan man tit blot starte
med at køre en grep efter 'reinterpret_cast' og dernæst 'const_cast' -
så har man en fin liste over de farligste konverteringer i hele
programmet.  Prøv at grep'e efter et C-style cast...   Ud over det, så
er det bare smæk-forkert at lære folk C-style casts - C++ har et
strengere type system (med mindre man lærer folk at omgå det), og det er
en kæmpe hjælp når man skriver programmer der er større end de 10
liniers eksempler som forfatteren dog selv har svært nok ved at få
korrekte.


Polymorfisme
============

I det første eksempel med de 'polymorfiske telefoner', bruger
forfatteren igen C-style cast.  Flot.  For det første er et cast ikke
nødvendigt, da arve-hierakiet gør tildelingen lovlig - for det andet
sikrer et C-style cast der, at hvis typer senere ændres sådan at
tildelingen ikke længere er det programmøren oprindeligt regnede med, så
vil fejlen ikke fanges under oversættelse, da C-style castet nok skal
sørge for at tildelingen bliver gennemført uanset hvad det så i øvrigt
er man tildeler...  Igen, unødvendigt, sjusket og farligt.  Præcist et
eksempel på hvad det er man *ikke* skal gøre i C++.

Han fortsætter sine eksempler med at bruge char arrays og strcpy() -
hvorfor i alverden han ikke bruger std::string og '=' forstår jeg
simpelt hen ikke...  Hvorfor gøre det farligt og besværligt, når det
sprog han forsøger at lære folk netop tillader at man gør det sikkert og
let?

Den dårlige stil fortsætter i bibliotekar/bog eksemplet med
pass-by-value af strukturer - hvorfor ikke en const reference? Hvorfor
lære folk at skrive ineffektiv kode når man netop kan skrive effektiv
kode sikkert og nemt?


Resten...
=============

Resten af øvelserne fortsætter med ekstremt farlig kode i utroligt
dårlig stil.  Det er "dårlig C", hvor han bruger nogle få udvalgte C++
features.  Een øvelse bruger intet af hvad man lærte øvelsen forinden -
han sørger for at man lærer "dårlig C med makroer", "dårlig C med
klasser", "dårlig C med templates", "dårlig C med iostream" - istedet
for blot stille og roligt at lære folk noget C++.

Det gør det ikke bedre at flere af øvelserne er direkte forkerte (vil
give segfault eller i bedste fald blot lække selvom forfatterens pointe
med eksemplet netop var at undgå læk).

Kort fortalt:  Jeg ved ikke præcist hvad det kapitel er, men det er
ihvertfald *ikke* en guide til C++.

Hvis resten af hæftet er af samme skuffe, så vil jeg anbefale at man
ikke bruger penge på det - hvis det var gratis ville det kun være spild
af tid.


Er der spørgsmål til noget af ovenstående skal jeg gøre mit bedste for
at svare  :)

 / jakob



 
Home   Subscribe   Mail Archive   Index   Calendar   Search

 
 
Questions about the web-pages to <www_admin>. Last modified 2005-08-10, 22:43 CEST [an error occurred while processing this directive]
This page is maintained by [an error occurred while processing this directive]MHonArc [an error occurred while processing this directive] # [an error occurred while processing this directive] *