Ich muss ehrlich sagen das C++ Tutorial war bis jetzt sehr spannend, ich habe viel gelernt.
Wenn du irgendwann mit dem neuen C++ Tutorial fertig bist, hast du dann vor das jetzige drin zu lassen?
Liebe Grüße
Von Xeon
Ich muss ehrlich sagen das C++ Tutorial war bis jetzt sehr spannend, ich habe viel gelernt.
Das ist eine gute Frage... ich werde vermutlich Teile davon wiederverwerten, denn ich bin grundsätzlich mit dem Aufbau zufrieden und das Know-How zum Thema Objektorientierung ist ja nicht veraltet.
Code: Alles auswählen
class Fraction
{
private:
int Numerator;
int Denominator;
public:
Fraction( int num, int den ) : Numerator( num ), Denominator( den ) {}
explicit Fraction( int num ) : Numerator( num ), Denominator( 1 ) {}
Fraction operator *( Fraction & rhs );
Fraction operator *( int rhs );
};
Fraction Fraction::operator *( int rhs )
{
Fraction result( *this );
result *= rhs;
return result;
}
Fraction Fraction::operator *( Fraction & rhs )
{
return Fraction( *this ) *= rhs;
}
int main(void)
{
Fraction a( 1, 2 ), b( 2, 3 );
a * b;
return 0;
}
Code: Alles auswählen
||=== Build: Debug in CplusplusTest (compiler: GNU GCC Compiler) ===|
In member function 'Fraction Fraction::operator*(int)':|
20|error: no match for 'operator*=' (operand types are 'Fraction' and 'int')|
In member function 'Fraction Fraction::operator*(Fraction&)':|
26|error: no match for 'operator*=' (operand types are 'Fraction' and 'Fraction')|
||=== Build failed: 2 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|
Code: Alles auswählen
class Tier
{
public:
char Name[64];
int Fellfarbe;
int KrallenLaenge;
int AnzahlBeine;
inline void GibNamenAus( void ) { printf( "Ich heiße %s\n", Name );
void (*GibLaut)( void );
Tier( void (*gibLaut)() ) : GibLaut( gibLaut ) {}
};
Code: Alles auswählen
Tier( void (*gibLaut)() ) : GibLaut( gibLaut ) {}
Code: Alles auswählen
Tier( void (*gibLaut)(void) ) : GibLaut( gibLaut ) {}
Code: Alles auswählen
inline void GibNamenAus( void ) { printf( "Ich heiße %s\n", Name );
Hmm... grundsätzlich gilt eher bei Funktionssignaturen das void in der Parameterliste weg zu lassen...Xeon hat geschrieben: ↑Do Jul 22, 2021 1:19 pmHallo zusammen
Mein Vorschlag wäre da eine Kleinigkeit zu ändern.
Ich würde bei dieser Zeilevoid zwischen den Klammern schreiben, für bessere Lesbarkeit, also so:Code: Alles auswählen
Tier( void (*gibLaut)() ) : GibLaut( gibLaut ) {}
Code: Alles auswählen
Tier( void (*gibLaut)(void) ) : GibLaut( gibLaut ) {}
Wieso vergess' ich da laufend Klammern?! Danke für's Hingucken!Xeon hat geschrieben: ↑Do Jul 22, 2021 1:19 pmDa ich schon dran bin, hier fehlt eine geschweifte Klammer am Ende:Code: Alles auswählen
inline void GibNamenAus( void ) { printf( "Ich heiße %s\n", Name );
Der C++ Standard ist hier eindeutig: Leere Klammern bedeuten die Funktion hat keine Parameter. Ich persönlich finde es daher nicht nötig, das durch void nochmals explizit hervorzuheben.Xin hat geschrieben: ↑Do Jul 22, 2021 6:13 pmHmm... grundsätzlich gilt eher bei Funktionssignaturen das void in der Parameterliste weg zu lassen...
Gleichzeitig stimme ich Dir allerdings zu, dass das void hier deutlicher darauf hinweist, dass es sich um eine Funktion handelt und die leeren Klammern leichter überlesen werden können.
nufan... Meinung?
Code: Alles auswählen
enum ObjType
{
OBJTYPE_CAT,
OBJTYPE_DOG,
OBJTYPE_BLACKBIRD
};
struct TierVTable
{
ObjType Type;
void (*GibLaut)();
int (*JageFutter)( struct Tier * );
char const * (*FutterArt)();
};
class Tier
{
public:
TierVTable & vtable;
char Name[64];
int Fellfarbe;
int KrallenLaenge;
int AnzahlBeine;
Tier( TierVTable & initVTable ) : vtable( initVTable ) {}
};
struct TierVTable TierVTableKatze;
struct TierVTable TierVTableHund;
struct TierVTable TierVTableAmsel;
class Hund : public Tier
{
public:
int GefangeneKatzen;
Hund() : Tier( TierVTableHund ) {}
};
class Katze : public Tier
{
public:
int GefangeneVoegel;
Katze() : Tier( TierVTableKatze ) {}
};
class Amsel : public Tier
{
public:
int GefangeneInsekten;
Amsel() : Tier( TierVTableAmsel ) {}
};
static void GibLautKatze() { printf( "Miau\n" ); }
static void GibLautHund() { printf( "Wuff\n" ); }
static void GibLautAmsel() { printf( "Piep\n" ); }
static char const * FutterArtKatze() { return "Vögel"; }
static char const * FutterArtHund() { return "Katzen"; }
static char const * FutterArtAmsel() { return "Insekten"; }
static int JageFutterKatze( class Tier * thisPtr ) { return ++static_cast< Katze * >( thisPtr )->GefangeneVoegel; }
static int JageFutterHund ( class Tier * thisPtr ) { return ++static_cast< Hund * >( thisPtr )->GefangeneKatzen; }
static int JageFutterAmsel( class Tier * thisPtr ) { return ++static_cast< Amsel * >( thisPtr )->GefangeneInsekten; }
void initVTables()
{
TierVTableKatze.Type = OBJTYPE_CAT;
TierVTableKatze.GibLaut = GibLautKatze;
TierVTableKatze.JageFutter = JageFutterKatze;
TierVTableKatze.FutterArt = FutterArtKatze;
TierVTableHund.Type = OBJTYPE_CAT;
TierVTableHund.GibLaut = GibLautHund;
TierVTableHund.JageFutter = JageFutterHund;
TierVTableHund.FutterArt = FutterArtHund;
TierVTableAmsel.Type = OBJTYPE_CAT;
TierVTableAmsel.GibLaut = GibLautAmsel;
TierVTableAmsel.JageFutter = JageFutterAmsel;
TierVTableAmsel.FutterArt = FutterArtAmsel;
}
void LautUndZweimalJagen( Tier * tier )
{
tier->vtable.GibLaut();
printf( "Tier fängt Nahrung: bisher %d %s gefangen\n", tier->vtable.JageFutter( tier ), tier->vtable.FutterArt() );
printf( "Tier fängt Nahrung: bisher %d %s gefangen\n", tier->vtable.JageFutter( tier ), tier->vtable.FutterArt() );
}
int main( void )
{
initVTables();
Tier *tier1, *tier2;
tier1 = new Katze();
tier2 = new Hund();
LautUndZweimalJagen( tier1 );
LautUndZweimalJagen( tier2 );
LautUndZweimalJagen( tier1 );
delete tier1;
delete tier2;
return EXIT_SUCCESS;
}
Code: Alles auswählen
TierVTableHund.Type = OBJTYPE_CAT;
TierVTableAmsel.Type = OBJTYPE_CAT;
Code: Alles auswählen
TierVTableHund.Type = OBJTYPE_DOG;
TierVTableAmsel.Type = OBJTYPE_BLACKBIRD;