Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

11

22.06.2015, 21:03

Zitat

Hier wird irgendwie der Falsche Begriff verwendet, es wird nichts
überschrieben, ich glaub Schorsch hat es schon gesagt der Konstruktor
der BasisKlasse wird Initialisiert.
Genau - ich brauchte nur einen simplen Standardkonstruktor und nach kurzer Zeit wurde mir das auch wieder bewusst. Ich habe nur theoretisch und bedingt mit Klassen gearbeitet und nun zeigt sich der Vorteil dieser nunmal vorallem bei größeren Programmen. Was ich da noch im Kopf hatte ist, wie bereits erwähnt Heiko Kalistas Aussage:

Zitat

Durch die Verwendung des Schlüsselwortes virtual direkt bei der
Deklaration einer Memberfunktion gibt man an, dass damit zu rechnen ist,
dass eine abgeleitete Klasse diese Funktion überschreiben wird.
Und dachte genau das muss hier getan werden, wobei absolut kein Bedarf danach bestand.

Danke für die Hinweise,

Lg

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Dareptor« (22.06.2015, 21:10)


12

22.06.2015, 22:12

Genau - ich brauchte nur einen simplen Standardkonstruktor und nach kurzer Zeit wurde mir das auch wieder bewusst. Ich habe nur theoretisch und bedingt mit Klassen gearbeitet und nun zeigt sich der Vorteil dieser nunmal vorallem bei größeren Programmen. Was ich da noch im Kopf hatte ist, wie bereits erwähnt Heiko Kalistas Aussage:


Ja es funktioniert wenn die Basis Klasse einen Standard Konstruktor hat, aber dem entnehme ich das du die Hinweise hier nicht ganz/wirklich verstanden hast.
Wenn die Basisklasse keinen Standard Konstuktor hat, hat das in der Regel einen Grund, meist der das beim Aufruf des Objektes es auch Initialisiert sein soll.
Genau so ist es wenn du den Konstruktor der Basis Klasse über den Konstruktor der Kind Klasse aufrufst, die Basis Klasse soll damit initialisert werden. Anderfalls müssen alle Parameter umständlich über eventuelle set-Methoden gesetzt werden.

nochmal ein Kleines Beispiel um die Sache zu verdeutlichen (im Prinzip identisch zu H5:: seinem Code).

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// ElterKlasse.hpp
class ElternKlasse
{
private:
    int m_parameter;
public:
    ElternKlasse(int paramater);
};

// ElternKlasse.cpp

ElternKlasse::ElternKlasse(int paramater) : // Initialisierungsliste
    m_parameter(parameter) 
{
    // Klasse ist initialisert
}

// KindKlasse.hpp
class KindKlasse : public Elternklasse
{
private:
    int m_parameter2;
public:
    KindKlasse(int parameter, int parameter2);
};

//KindKlasse.cpp

KindKlasse::KindKlasse(int parameter, int parameter2) : // Initialisierungsliste
    ElternKlasse(parameter), // Elternklasse Initialisieren
    m_parameter2(parameter2)
{
     // Klasse ist initialisert (auch die ElternKlasse ohne Standard Konstruktor)
}


Zitat

Durch die Verwendung des Schlüsselwortes virtual direkt bei der
Deklaration einer Memberfunktion gibt man an, dass damit zu rechnen ist,
dass eine abgeleitete Klasse diese Funktion überschreiben wird.

Übrigens der Kostruktor ist keine Memberfunktion.
Wer aufhört besser werden zu wollen hört auf gut zu sein!

aktuelles Projekt:Rickety Racquet

13

22.06.2015, 23:03

So wie sich das liest hat eine Initialisierungsliste nur Vorteile. In welchen Fällen sollte ich keine Initialisierungsliste verwenden, wenn ich meinen Konstruktor überlade ? Sollte ich grundsätzlich davon ausgehen, dass eine Initialisierungsliste der bessere Weg ist, wenn ich meinen Konstruktor überlade ? Was ist der Nachteil einer Initialisierungsliste ?

14

23.06.2015, 02:11

In welchen Fällen sollte ich keine Initialisierungsliste verwenden, wenn ich meinen Konstruktor überlade ?
Fällt mir keiner ein.

Sollte ich grundsätzlich davon ausgehen, dass eine Initialisierungsliste der bessere Weg ist, wenn ich meinen Konstruktor überlade ?
Ja.

Was ist der Nachteil einer Initialisierungsliste ?
Sind mir keine Bekannt.
Wer aufhört besser werden zu wollen hört auf gut zu sein!

aktuelles Projekt:Rickety Racquet

birdfreeyahoo

Alter Hase

Beiträge: 756

Wohnort: Schorndorf

Beruf: Junior Software Engineer

  • Private Nachricht senden

15

23.06.2015, 02:54

Was ist der Unterschied wenn ich eine Initialisierungsliste verwende, gegenüber dem, dass ich die Zuweisungen im Rumpf mache?

16

23.06.2015, 05:37

Was ist der Unterschied wenn ich eine Initialisierungsliste verwende, gegenüber dem, dass ich die Zuweisungen im Rumpf mache?

Das man es nicht schafft eine Klasse zu erzeugen wie in meinem Bsp. (Basisklasse ohne standard Konstruktor), der rest würde auch im Rumpf funktionieren (Abhängig von der Implementierung des jeweiligen typs z.B. Klassen mit privatem zuweisungsoperator gehen nicht).
Wer aufhört besser werden zu wollen hört auf gut zu sein!

aktuelles Projekt:Rickety Racquet

H5::

Treue Seele

Beiträge: 368

Wohnort: Kiel

  • Private Nachricht senden

17

23.06.2015, 14:01

Oder für so etwas (Referenzen):

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class A {
    const int& m;

public:
    A(const int& p) : m(p) {

    }
};

class B {
    const int& m;

    B(const int& p) { // error: constructor for 'B' must explicitly initialize the reference member 'm'
        m = p; 
    }
};
:love: := Go;

birdfreeyahoo

Alter Hase

Beiträge: 756

Wohnort: Schorndorf

Beruf: Junior Software Engineer

  • Private Nachricht senden

18

23.06.2015, 14:17

Wenn ich Festwertzuweisungen direkt an der Variablendeklaration mache...

C-/C++-Quelltext

1
2
3
4
5
class A
{
    int i = 5;
    ....
};


Wird das dann auch unsichtbar in die Initialisierungsliste eingetragen?

H5::

Treue Seele

Beiträge: 368

Wohnort: Kiel

  • Private Nachricht senden

19

23.06.2015, 14:31

Du solltest Laufzeit und Übersetzungszeit unterscheiden. Wobei wohl (Nicht getestet) der Compiler aus den beiden Beispielen eventuell das Gleiche machen wird.

C-/C++-Quelltext

1
2
3
4
5
6
class A {
    int m = 5;

public:
    A() { }
};

C-/C++-Quelltext

1
2
3
4
5
6
class B {
    int m;

public:
    B() : m(5) { }
};


Edit: Beachte aber folgendes: (Das char hat keine weitere Bedeutung außer um einen 3. Konstruktor zu erhalten)

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
class C {
    int m;

public:
    C() : m(5) { }
    C(int p) : m(p) { }
    C(char p) { }

    auto print() { std::printf("%d\n", m); }
};

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
class D {
    int m = 5;

public:
    D() : m(2) { }
    D(int p) : m(p) { }
    D(char p) { }

    auto print() { std::printf("%d\n", m); }
};
:love: := Go;

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »H5::« (23.06.2015, 14:50)


20

24.06.2015, 23:08

Ich hätte nochmal eine Frage zu den Initialisierungslisten

Mein Code sieht wie folgt aus (CPlayer erbt von CCharacter und ruft den Konstruktor mithilfe einer Initalisierungsliste auf):

C-/C++-Quelltext

1
2
3
4
CPlayer::CPlayer(int x, int y) :
CCharacter(x, y, true, 100)
{
}


Nun möchte ich gerne von der member Variable CTexture eine Funktion aufrufen. Wie realisiere ich das ? Hierfür müsste ich dann auf dem herkömmlichen Weg diese im Funktionsrumpf aufrufen, richtig ?
Das ganze würde dann wie folgt aussehen:

C-/C++-Quelltext

1
2
3
4
5
CPlayer::CPlayer(int x, int y) :
CCharacter(x, y, true, 100)
{
    mTextureNormal.loadFromFile("D:/...");
}


Kann ich das ganze auch mit Initialisierungslisten machen, oder ist das generell schlechter Code, welcher so nicht existieren sollte ?

Werbeanzeige