"Preben Holm" <64bitNOSPAMNO@mailme.dk> wrote in message
news:4331be97$0$255$14726298@news.sunsite.dk...
[8<8<8<]
> Okay... Men kan du forklare mig pointen i namespaces?
Pointen er at kunne skelne 2 klasser der hedder det samme (f.eks. string -
altså std::string og my_lib::string).
Forestil dig at nogen skriver
using std::string
i een header fil.
I en anden header fil skriver man
using my_lib::string;
Så kan man ikke længere skelne hvilken type der menes når man skriver
void foo(const string& param);
I særdeleshed kan man ikke overskue hvilken kode man får til at holde op med
at virke hvis man på et tidspunkt tilføjer
using std::string;
til en header fil.
> Eller henvise til en god forklaring.
Det er langt bedre end hvad man hurtigt kan forklare på en nyhedsgruppe.
Se bogen
C++ Coding Standards
Herb Sutter, Andrei Alexandrescu
ISBN 0-321-11358-6
Item 59.
Det er i det hele taget en god bog - det fåes ikke meget bedre.
I samme omgang bør man nævne
Exceptional C++
Herb Sutter
ISBN 0-201-61562-2
More Exceptional C++
Herb Sutter
ISBN 0-201-70434-X
Effective C++:
Scott Meyers
ISBN: 0-321-33487-6
(det er den nye 3. udgave som jeg ikke har læst - men jeg tør godt antage at
den er god)
More Effective C++: 35 New Ways to Improve Your Programs and Designs
Scott Meyers
ISBN: 0-201-63371-X
Effective STL
Scott Meyers
ISBN: 0-201-74962-9
og så naturligvis
The C++ Programming Language, Special Edition
Bjarne Stroustrup
ISBN 0-201-70073-5
>
> Er lige startet på at lære C++ i forrige uge, og skulle gerne "mestre" det
> inden for 6 uger (altså 3½ uge endnu) - utopi, det tror jeg nok det er,
> men ikke desto mindre et faktum.
Det tager lang tid at komme til bunds, men man kan komme rigtigt langt på et
par uger hvis man bruger det rigtige grundlag til at lære fra (Se reference
længere nede).
>
> Bør f.eks. "using std::string" stå indenfor namespace
Man kan skrive det inde i en klasse erklæring eller funktions definition -
men det er simplest bare helt at lade være med at skrive det i en header
fil.
> eller udenfor namespace i .cpp-filer?
Ja, det skader ikke - for der er ikke nogen der inkluderer en cpp fil -:)
[8<8<8<]
> Nej, først når "lortet" ikke kompilerer korrekt!
Det er ikke for at være efter dig - men for at lære.
[8<8<8<]
> og hvis du vidste hvor lang tid jeg har ledt efter en funktion som bare
> kunne smide linien over i et streng-objekt istedet for et irriterende
> char-array, så havde livet været meget lettere for mig.
Ok - så er vi ved en af mine absolut favorit bøger til indtroduktion af C++:
Accelerated C++
Andrew Koenig, Barbara E. Moo
ISBN 0-201-70353-X
som beskriver det på side 91.
Selvom bogen ikke beskriver hele sproget, så indeholder den hvad du har brug
for til at lave et program i stil med hvad du viser.
Bogen er ikke særligt stor og let at læse.
Kode stilen i bogen ligger tæt på hvad jeg bruger længere nede i dette
indlæg.
Har du skrevet Java tidligere (brugen af "new" og navne konventionen tyder
på det) ?
>
> Men der er jo utallige af ufatteligt ringe eksempler rundt omkring på
> nettet hvor der er utroligt mange eksempler på "slam".
Ja - det er rigtigt ærgeligt og et reelt problem.
Derfor opfordrer jeg også altid til at bruge _gode_ bøger (der findes
_mange_ dårlige) i stedet for mere eller mindre tilfældige hjemmesider, og
jeg plejer (som i dette indlæg) at angive en række _gode_ bøger.
[8<8<8<]
>> Der bliver oprettet kopi af device - hvem ejer så Property og Attribute
>
> Ehh... undskyld, men den kopi af device som oprettes, vil vel have samme
> pointer til Property og Attribute som i det objekt der ligger på stacken?
> Så "device" i vector og "device" på stack refererer vel stadig til samme
> objekt?
Ja, hvis din Device ligner noget i retning af:
class Device
{
//...
private:
Propety* property;
// eller
vector<Property*> properties;
};
og du ikke har gjort noget for at implementere en copy constructor og copy
assignment.
Problemet er at du har 2 "Device" objekter som peger på samme Property
objekt - hvem har ansvaret for at nedlægge Property objektet ?
Hvis "Device" destructoren nedlægger den:
Device:
Device()
{
delete property;
}
så vil det første "Device" objekt der bliver nedlagt ødelægge livet for det
andet "Device" objekt.
Hvis destructoren ikke nedlægger "property" hvem gør så ?
Det kan sagtens håndteres med f.eks. reference counting eller endnu nemmere
med boost::shared_ptr (se
http://www.boost.org/libs/smart_ptr/shared_ptr.htm), som nogenlunde bliver
en del af den kommende C++ Standard.
class Device
{
// ...
private:
boost::shared_ptr<Property> property;
};
så skal du ikke gøre yderligere.
Det er enkelt og effektivt.
Det er blot endnu nemmere at undgå det til at begynde med, hvis man ikke har
brug for det.
Et eksempel hvor det ikke kan undgås er hvis Property er en abstrakt
basisklasse og "Device" ikke ved om det konkret er f.eks. "StringProperty"
eller "IntProperty" den indeholder.
Det er nemmere hvis Device, Property og Attribute har value semantik (som
f.eks. "int" og "std::string").
Så skriver man blot (ikke oversat kode):
class Device
{
//...
void addProperty(const std::string& PropertyValue);
void addAttribute(const std::string& AttributeValue);
private
vector<Property> properties;
vector<Attribute> attributes;
};
void Device::addProperty(const std::string& PropertyValue)
{
properties.push_back(Property(PropertyValue));
}
Så har du ikke nogen "new" og derfor heller ikke brug for at skrive "delete"
nogen steder.
> Eller har jeg misforstået noget?
Spørgsmålet er mere om du har gjort dig overvejelsen.
Hvis du programmerer i Java eller C# er der ikke noget at overveje - bortset
fra objekt levetid generelt.
Når man programmerer i C++ er der heller ikke noget at overveje, hvis man
bruger en passende kodestil (2 eksempler er givet i dette indlæg).
>
> (bortset fra at Property og Attribute gemmes i en vector og derfor faktisk
> kopieres istedet -> memory leak)
Memory leak er ikke tilladt
[8<8<8<]
>> Du skulle vel ikke have includeret DeviceParser.cpp i din main.cpp ?
>
> Jo... Det har jeg... og hvis du vidste hvor mange timer - mange timer jeg
> har ledt efter den fejl, så grinede du mere end du allerede gør..
Jeg griner ikke.
Jeg tør væde på at jeg har dummet mig på flere måder end du kan forestille
dig i de mere end 15 år jeg har programmeret C++
Hvordan skulle jeg ellers være i stand til at svare ?
Venlig hilsen
Mogens Hansen