Ny til c++: Fatter hat af funktioner

Tags:    c++

<< < 12 > >>
Jeg har besluttet mig for at lære c++. Det er et rimelig overvældende sprog og meget svært, men jeg synes det går stødt frem ad.
I min online guide er jeg dog nu kommet til noget som jeg simpelthen ikke kan forstå:
http://cma.zdnet.com/book/c++/htm/ch10.htm

I listing 10.2 støder man på følgende i linie 14:
void DrawShape(USHORT aWidth, USHORT aHeight, BOOL UseCurrentVals = Â FALSE) const;

Hvad betyder  FALSE?

Senere i linie 29-33 skifter funktionen DrawShape lige pludselig parametre til width, height og UseCurrentValue i stedet for aWidth, aHeight og UseCurrentVals som står i prototypen i linie 14. Hvorfor og hvordan?

Og så lige den sidste ting: I linie 22-25 bliver constructoren defineret. Hvad betyder:
itsWidth(width),
itsHeight(height)
{}
og hvorfor er kroppen tom?

Håber i kan hjælpe, på forhånd tak :)

[Redigeret d. 10/02-06 20:15:27 af noname]



Kendte ikke lige til default værdier, men som de indirekte forklarer længere nede gør UseCurrentVals = Â FALSE at DrawShape kan kaldes som DrawShape(10,2) (UseCurrenVals bliver FALSE) samt DrawShape(10,2,true) (UseCurrenVals bliver true). Dog tror jeg at "Â " er en fejl, da jeg får meddelt fejl med dette i koden, dvs kun:
void DrawShape(USHORT aWidth, USHORT aHeight, BOOL UseCurrentVals = FALSE) const;

Med hensyn til navnefornadringen fra awidth til with og aheight til height, er det bare forfatteren som ikke har holdt styr på at kalde variablerne det samme begge steder som jeg ser det.

Til sidst er:
itsWidth(width),
itsHeight(height)
{}
det samme som:
itsWidth=width;
itsHeight=height;
itsWidth(width) og itsHeight(height) er blot normale måde at initialisere variabler på i constructorer, og da der kun foregår initialisering af variablerne i klassen med angivne argumenter, da er {} tom.

Desuden mangler der vist også en using namespace std; i starten

[Redigeret d. 10/02-06 19:50:42 af Andreas]



Tak skal du have, det hjalp en del. Forfatteren undgår konsekvent at skrive using namespace std; hvorfor aner jeg ikke. Der er ikke et eneste kode eksempel hvor det bliver brugt. Måske har han inkluderet det i iostream.h og bare glemt at fortælle om det?

Jeg tror nu der er en dybere mening med  da jeg er stødt på det op til flere gange.

Det virker rimelig uproffesionelt at variablerne pludselig skifter navn. Jeg synes ellers at "Teach YourSelf Visual Basic in 21 Days" var rigtig god, den er også fra Sam's Publishing.



Tak skal du have, det hjalp en del. Forfatteren undgår konsekvent at skrive using namespace std; hvorfor aner jeg ikke. Der er ikke et eneste kode eksempel hvor det bliver brugt. Måske har han inkluderet det i iostream.h og bare glemt at fortælle om det?

Jeg tror nu der er en dybere mening med  da jeg er stødt på det op til flere gange.

Det virker rimelig uproffesionelt at variablerne pludselig skifter navn. Jeg synes ellers at "Teach YourSelf Visual Basic in 21 Days" var rigtig god, den er også fra Sam's Publishing.


iostream.h er forældet, brug i stedet bare iostream. Men når man går det, så skal man bruge using namespace std; - det skal man ikke ellers, så det er i hvert fald ikke en fejl.

Det med funktionerne behøves heller ikke at være en fejl, man kan sagtens sende forskellige parametre til en funktion. Om det skal være tilfældet, kan jeg dog ikke sige.



Tak skal du have, det hjalp en del. Forfatteren undgår konsekvent at skrive using namespace std; hvorfor aner jeg ikke. Der er ikke et eneste kode eksempel hvor det bliver brugt. Måske har han inkluderet det i iostream.h og bare glemt at fortælle om det?

Jeg tror nu der er en dybere mening med  da jeg er stødt på det op til flere gange.

Det virker rimelig uproffesionelt at variablerne pludselig skifter navn. Jeg synes ellers at "Teach YourSelf Visual Basic in 21 Days" var rigtig god, den er også fra Sam's Publishing.


iostream.h er forældet, brug i stedet bare iostream. Men når man går det, så skal man bruge using namespace std; - det skal man ikke ellers, så det er i hvert fald ikke en fejl.

Det med funktionerne behøves heller ikke at være en fejl, man kan sagtens sende forskellige parametre til en funktion. Om det skal være tilfældet, kan jeg dog ikke sige.


Jeg har lige tjekket koden, og det må være to forskellige metoder, og så kunne  FALSE være med for sikre, at der kaldes den metode, der bliver deklareret i linje 29-33 anden gang, theRect() kaldes fra main.

Håber det var hjælp nok.

Edit: Det er overloadede funktioner, og eksemplet er med for at vise, at kompileren selv finder ud af, hvilken funktion der skal kaldes via parametrene. Irriterende, at jeg har afleveret C++ Grundbog (den oversatte version), ellers kunne jeg have fortalt, hvad der stod der i. Det ville nok have været det letteste.

[Redigeret d. 10/02-06 20:47:04 af Michael]



Jeg er nu kommet til afsnittet om preprocessoren (dag 17). Jeg forstår ikke helt pointen med at assert() kun bliver defineret hvis DEBUG er defineret som der står i afsnittet der hedder assert(). Det givne eksempel (listing 17.5) ser således ud:

1: // Listing 17.5 ASSERTS
2: #define DEBUG
3: #include <iostream.h>
4:
5: #ifndef DEBUG
6: #define ASSERT(x)
7: #else
8: #define ASSERT(x) \9: if (! (x)) \10: { \11: cout << "ERROR!! Assert " << #x << " failed\\n"; \12: cout << " on line " << __LINE__ << "\\n"; \13: cout << " in file " << __FILE__ << "\\n"; \14: }
15: #endif

I linie 5 bliver ASSERT(x) defineret hvis DEBUG netop IKKE er defineret. I linie 8 bliver ASSERT(x) defineret hvis DEBUG netop ER defineret - ASSERT(x) bliver altså defineret uanset hvad. Nogen der kan forklare dette for mig?



Ideen er at man definer ASSERT til at være ingenting hvis DEBUG ikke er defineret og til at skrive en fejlbesked hvis ASSERT er defineret.

Derved kan man bruge ASSERT i sin kode, sålænge man debugger sætter man DEBUG og får udskrevet en fejlbesked. Når man releaser sin kode definerer man ikke DEBUG og koden forsvinder dermed. Og man er fri for at fjerne alle sine ASSERT's

Et andet eksempel på det samme kunne være et trace statement der udskrever en linie til en fil hvis DEBUG er defineret og ingenting hvis ikke DEBUG er defineret.



Jeg har forstået ideen med assert, som du korrekt skriver bliver den kun defineret hvis DEBUG er defineret. MEn hvordan afspejler det sig i den kode jeg har skrevet? Det er det jeg ikke kan se. Er det en method i selve assert()?



ASSERT bliver defineret til to forskellige ting afhængigt af om debug er defineret.

Så hvis du har:
Fold kodeboks ind/udKode 


Kan du få main til at udskrive en besked eller foretage intet afhængigt af om DEBUG er defineret, uden at ændre i main.
Det kan være praktisk at have en masse trace output når man udvikler, men brugeren af programmet vil nok helst ikke se på det output. Når ud så udvikler sætter du en gang for alle DEBUG og du får dit trace og når du frigiver til kunden definerer du ikke DEBUG og trace statements bliver til ingenting. Du kunne opnå det samme med et flag, og en if(...) men det vil netop fylde i koden, din ASSERT fylder intet hvis ikke DEBUG er defineret.

Der findes en debug macro kaldet assert i assert.h, der gør stort set det samme som din ASSERT, den styrres af NDEBUG på samme (modsatte) måde som din DEBUG.

Bemærk i øvrigt at iostream.h ikke er en standard header-fil; brug iostream og skriv using namespace std; som i mit eksempel.



Hvis man fjerner #define DEBUG fra koden vil den tomme funktion TRACE(x) blive defineret - jf. #ifndef DEBUG. Skal det så forståes således at fordi funktionen er tom fylder den intet i programmet? Den bliver ganske enkelt ignoreret af compileren?
Jeg er lidt forvirret i C++ standarderne, jeg er lige startet. Det kræver noget tilvænning at holde styr på alle de mange ting man lærer.



Ja, det bliver ignoreret af compileren (eller hvis man vil være pedantisk af preprocessoren (med det er normalt en del af compileren))

Man kunne også skrive mit eksempel som:

Fold kodeboks ind/udKode 

Man hvis man skal bruge det 1203 steder i koden bliver det lidt trivielt.

Hvis DEBUG ikke er defineret compileres cout << ... slet ikke med i koden.



<< < 12 > >>
t