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

1

22.03.2013, 18:55

Zu listing 7.14 Problem beim aufrufen der Memberfunktion einer Abgeiteten Klasse

Hallo erstmal,

ich habe folgendes Problem,
beim Listing 7.14, wurde eine klasse CRaumschiff erstellt welche als Basisklasse dienen soll, des weiteren wurde eine weiterer Klasse CMinenleger erstellt,
die jetzt alles von CRaumschiff erbt.

im main() wird dann eine instanz erzeugt und zwar folgendermaßen

CRaumschiff *Schiff;
Schiff = new CMinenleger;

später wird dann darauf hingewiesen das ich mit dieser Instanz nicht auf die Memberfunktions von CMinenleger zugreifen kann, ausser wenn ich in der Basisklasse Funktionen mit virtual kennzeichne und diese in der Abgeleiteten Klasse ersetze???!

Meine Frage lautet nun wie ich es hinbekomme, dass das funktioniert, dass ich also auf diese Funktionen zugreifen kann...

Im Buch wird ja drauf hingewiesen das es irgendwie Funktioniert

Hier nochmal zur Sicherheit das gesamte Listing...

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// C++ f�r Spieleprogrammierer
// Listing 7.14
// Virtuelle Funktionen
//
#include <iostream>

using namespace std;

// Klassen
//

// Basisklasse
//
class CRaumschiff
{
    protected:

        // Membervariablen
        int m_Farbe;
        int m_Energie;

    public:

        // Memberfunktionen
        CRaumschiff ()
        {
            m_Farbe = 0;
            m_Energie = 1000;
            cout << "Neues Raumschiff erstellt" << endl;
        }

        virtual ~CRaumschiff () {cout << "Destruktor Basisklasse\n";}

        virtual void Starten () {cout << "Raumschiff startet!\n";}
        virtual void Landen  () {cout << "Raumschiff landet!\n";}

};

// Abgeleitete Klasse f�r den Minenleger
//
class CMinenleger : public CRaumschiff
{
    private:

        // Membervariablen
        int m_Minen;

    public:

        // Memberfunktionen
        CMinenleger ()
        {
            m_Minen = 10;
            cout << "Neuer Minenleger erstellt" << endl;
        };

        ~CMinenleger () {cout << "Destruktor Minenleger\n";}

        void Starten () {cout << "Minenleger startet!\n";}
        void Landen  () {cout << "Minenleger landet!\n";}
                void Minen_Legen() {Minen--;}       //von mir hinzugefügt

};

// Hauptprogramm
//
int main ()
{
    // Variablen
    //
    CRaumschiff *Schiff; // Ein Raumschiff

    Schiff = new CMinenleger; // Ein Minenleger soll es sein

    // Minenleger f�hrt einige Aktionen aus
    Schiff->Starten ();
    Schiff->Landen ();
        Schiff->Minen_Legen(); //compilerfehler

    delete Schiff;  // Raumschiff zerst�ren

    return 0;
}

2

22.03.2013, 23:12

Ich verstehe deine Frage jetzt nicht genau, deshalb versuche ich es mal zu erklären ^^

Wenn du eine Funktion als virtual deklarierst ist das sozusagen der Hinweis darauf, dass diese Funktion in einer abgeleiteten Klasse überschrieben wird.
Überschreibst du die Funktion in der abgeleiteten klasse, ersetzt du dadurch die Funktion in der Basisklasse und es wird nur die von der abgeleiteten klasse ausgeführt.

Würdest du die Funktion nicht als virtual deklarieren, würdest du beim aufrufen der Funktion nur die Funktion der Basisklasse aufrufen und nicht die Funktion der abgeleiteten Klasse.

Falls ich etwas falsch Erklärt habe bitte ich es zu korrigieren :)

Mit freundlichen Grüßen,
Ombalat

3

23.03.2013, 00:11

Der Fehler (Zeile 79) tritt auf, weil dein Pointer vom Typ CRaumschiff keine Funktion Minen_Legen() enthält. Du müsstest entweder ein Objekt vom Typ CMinenleger erzeugen bzw. in ein solches casten oder (sinnloserweise) die Funktion virtuell in CRaumschiff implementieren.

4

23.03.2013, 08:59

Anders geht es nicht?

Was wäre , wenn ich sagen wir, mehrere Raumschiffe habe und durch auswählen mir meines zusammenstelle, alle sollen grundeigenschaften besitzen, die in CRaumschiff enthalten sind und zusätzliche die in CMineleger enthallten sind...

Wie würde das mit dem casten in diesem bsp funktionieren...

Sorry wegen der vlt dummen frage ^^..

Cookiezzz

Frischling

Beiträge: 91

Wohnort: Deutschland

Beruf: Schüler

  • Private Nachricht senden

5

23.03.2013, 09:35

Hi,

wenn du auf die Funktionen von CMinenleger zugreifen willst, muss auch dein Pointer von diesem Typ sein. Das mit dem casten an der STelle würde ich vergessen, das ist nicht wirklich guter Programmierstil. Du musst dir die Beziehung zwische CRaumschiff und CMinenleger verdeutlichen. Die Vererbung bedeutet im Prinzip "CMinenleger ist ein CRaumschiff", aber nicht andersherum. Somit hat CMinenleger alle Eigenschaften eines Raumschiffes, aber nicht anders herum(Nicht jede Raumschiff kann Minen legen). Wenn du Minen legen willst, muss der Pointer also auch vom Typ Minenleger sein, da ansonsten nicht sicher ist, ob das Schiff überhaupt Minen legen kann. Alternativ könnte man für CRaumschiff auch eine allgemeinere Funktion definieren, z.B entladen() oder ähnliches. Hier könnte der Minenleger dann seine Minen abwerfen, ein Handelsschiff könnte Kisten ausräumen. Nochmal als 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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// C++ f�r Spieleprogrammierer
// Listing 7.14
// Virtuelle Funktionen
//
#include <iostream>

using namespace std;

// Klassen
//

// Basisklasse
//
class CRaumschiff
{
    protected:

        // Membervariablen
        int m_Farbe;
        int m_Energie;

    public:

        // Memberfunktionen
        CRaumschiff ()
        {
            m_Farbe = 0;
            m_Energie = 1000;
            cout << "Neues Raumschiff erstellt" << endl;
        }

        virtual ~CRaumschiff () {cout << "Destruktor Basisklasse\n";}

        virtual void Starten () {cout << "Raumschiff startet!\n";}
        virtual void Landen  () {cout << "Raumschiff landet!\n";}
        virtual void Entladen ()=0;

};

// Abgeleitete Klasse f�r den Minenleger
//
class CMinenleger : public CRaumschiff
{
    private:

        // Membervariablen
        int m_Minen;

    public:

        // Memberfunktionen
        CMinenleger ()
        {
            m_Minen = 10;
            cout << "Neuer Minenleger erstellt" << endl;
        };

        ~CMinenleger () {cout << "Destruktor Minenleger\n";}

        void Starten () {cout << "Minenleger startet!\n";}
        void Landen  () {cout << "Minenleger landet!\n";}
        void Entladen () 
        {
            if(m_Minen <= 0)
            {
                cout << "Minen gelegt\n";
                m_Minen--;
            }
            else
                cout << "Keine Minen mehr da!\n";
        }

};


// Abgeleitete Klasse f�r den Minenleger
//
class Handelsraumschiff : public CRaumschiff
{
    private:

        // Membervariablen
        int m_Container;

    public:

        // Memberfunktionen
        Handelsraumschiff ()
        {
            m_Container = 10;
            cout << "Neues Handelsschiff erstellt" << endl;
        };

        ~Handelsraumschiff () {cout << "Destruktor Handelsraumschiff\n";}

        void Starten () {cout << "Handelsraumschiff startet!\n";}
        void Landen  () {cout << "Handelsraumschiff landet!\n";}
        void Entladen () 
        {
            if(m_Container <= 0)
            {
                cout << "Container ausgeladen\n";
                m_Minen--;
            }
            else
                cout << "Keine Container an Bord!\n";
        }

};

// Hauptprogramm
//
int main ()
{
    // Variablen
    //
    CRaumschiff *Schiff; // Ein Raumschiff

    Schiff = new CMinenleger; // Ein Minenleger soll es sein
    //Schiff = new Handelsschiff; -> Schiff wird zum Handelsschiff, keine weiteren Codeänderungen nötig.

    // Minenleger f�hrt einige Aktionen aus
    Schiff->Starten ();
    Schiff->Landen ();
    Schiff->Entladen();

    delete Schiff;  // Raumschiff zerst�ren

    return 0;
}



PS: Code nicht getestet!

6

23.03.2013, 10:05

Cookiezzz, was du da jetzt gesagt hast habe ich mir auch schon gedacht, dass es wahrscheinlich so sein wird, dachte aber vlt gibts da irgendeine cool und einfache Methode wie das trotzdem funktionieren könnte, so wie ich mir das vorgestellt habe...ˆˆ

aber egal, muss ichs halt so machen...

Auf jedenfall Danke für die Schnellen und tollen Antworten von euch allen! ;)

Werbeanzeige